src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp

changeset 3536
95f6641e38e0
parent 3181
c63b928b212b
child 3900
d2a62e0f25eb
     1.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Mon Feb 06 12:18:24 2012 -0800
     1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Fri Feb 10 17:40:20 2012 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -247,167 +247,6 @@
    1.11    }
    1.12  }
    1.13  
    1.14 -//
    1.15 -// This method is pretty bulky. It would be nice to split it up
    1.16 -// into smaller submethods, but we need to be careful not to hurt
    1.17 -// performance.
    1.18 -//
    1.19 -
    1.20 -oop PSPromotionManager::copy_to_survivor_space(oop o) {
    1.21 -  assert(PSScavenge::should_scavenge(&o), "Sanity");
    1.22 -
    1.23 -  oop new_obj = NULL;
    1.24 -
    1.25 -  // NOTE! We must be very careful with any methods that access the mark
    1.26 -  // in o. There may be multiple threads racing on it, and it may be forwarded
    1.27 -  // at any time. Do not use oop methods for accessing the mark!
    1.28 -  markOop test_mark = o->mark();
    1.29 -
    1.30 -  // The same test as "o->is_forwarded()"
    1.31 -  if (!test_mark->is_marked()) {
    1.32 -    bool new_obj_is_tenured = false;
    1.33 -    size_t new_obj_size = o->size();
    1.34 -
    1.35 -    // Find the objects age, MT safe.
    1.36 -    int age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
    1.37 -      test_mark->displaced_mark_helper()->age() : test_mark->age();
    1.38 -
    1.39 -    // Try allocating obj in to-space (unless too old)
    1.40 -    if (age < PSScavenge::tenuring_threshold()) {
    1.41 -      new_obj = (oop) _young_lab.allocate(new_obj_size);
    1.42 -      if (new_obj == NULL && !_young_gen_is_full) {
    1.43 -        // Do we allocate directly, or flush and refill?
    1.44 -        if (new_obj_size > (YoungPLABSize / 2)) {
    1.45 -          // Allocate this object directly
    1.46 -          new_obj = (oop)young_space()->cas_allocate(new_obj_size);
    1.47 -        } else {
    1.48 -          // Flush and fill
    1.49 -          _young_lab.flush();
    1.50 -
    1.51 -          HeapWord* lab_base = young_space()->cas_allocate(YoungPLABSize);
    1.52 -          if (lab_base != NULL) {
    1.53 -            _young_lab.initialize(MemRegion(lab_base, YoungPLABSize));
    1.54 -            // Try the young lab allocation again.
    1.55 -            new_obj = (oop) _young_lab.allocate(new_obj_size);
    1.56 -          } else {
    1.57 -            _young_gen_is_full = true;
    1.58 -          }
    1.59 -        }
    1.60 -      }
    1.61 -    }
    1.62 -
    1.63 -    // Otherwise try allocating obj tenured
    1.64 -    if (new_obj == NULL) {
    1.65 -#ifndef PRODUCT
    1.66 -      if (Universe::heap()->promotion_should_fail()) {
    1.67 -        return oop_promotion_failed(o, test_mark);
    1.68 -      }
    1.69 -#endif  // #ifndef PRODUCT
    1.70 -
    1.71 -      new_obj = (oop) _old_lab.allocate(new_obj_size);
    1.72 -      new_obj_is_tenured = true;
    1.73 -
    1.74 -      if (new_obj == NULL) {
    1.75 -        if (!_old_gen_is_full) {
    1.76 -          // Do we allocate directly, or flush and refill?
    1.77 -          if (new_obj_size > (OldPLABSize / 2)) {
    1.78 -            // Allocate this object directly
    1.79 -            new_obj = (oop)old_gen()->cas_allocate(new_obj_size);
    1.80 -          } else {
    1.81 -            // Flush and fill
    1.82 -            _old_lab.flush();
    1.83 -
    1.84 -            HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize);
    1.85 -            if(lab_base != NULL) {
    1.86 -              _old_lab.initialize(MemRegion(lab_base, OldPLABSize));
    1.87 -              // Try the old lab allocation again.
    1.88 -              new_obj = (oop) _old_lab.allocate(new_obj_size);
    1.89 -            }
    1.90 -          }
    1.91 -        }
    1.92 -
    1.93 -        // This is the promotion failed test, and code handling.
    1.94 -        // The code belongs here for two reasons. It is slightly
    1.95 -        // different thatn the code below, and cannot share the
    1.96 -        // CAS testing code. Keeping the code here also minimizes
    1.97 -        // the impact on the common case fast path code.
    1.98 -
    1.99 -        if (new_obj == NULL) {
   1.100 -          _old_gen_is_full = true;
   1.101 -          return oop_promotion_failed(o, test_mark);
   1.102 -        }
   1.103 -      }
   1.104 -    }
   1.105 -
   1.106 -    assert(new_obj != NULL, "allocation should have succeeded");
   1.107 -
   1.108 -    // Copy obj
   1.109 -    Copy::aligned_disjoint_words((HeapWord*)o, (HeapWord*)new_obj, new_obj_size);
   1.110 -
   1.111 -    // Now we have to CAS in the header.
   1.112 -    if (o->cas_forward_to(new_obj, test_mark)) {
   1.113 -      // We won any races, we "own" this object.
   1.114 -      assert(new_obj == o->forwardee(), "Sanity");
   1.115 -
   1.116 -      // Increment age if obj still in new generation. Now that
   1.117 -      // we're dealing with a markOop that cannot change, it is
   1.118 -      // okay to use the non mt safe oop methods.
   1.119 -      if (!new_obj_is_tenured) {
   1.120 -        new_obj->incr_age();
   1.121 -        assert(young_space()->contains(new_obj), "Attempt to push non-promoted obj");
   1.122 -      }
   1.123 -
   1.124 -      // Do the size comparison first with new_obj_size, which we
   1.125 -      // already have. Hopefully, only a few objects are larger than
   1.126 -      // _min_array_size_for_chunking, and most of them will be arrays.
   1.127 -      // So, the is->objArray() test would be very infrequent.
   1.128 -      if (new_obj_size > _min_array_size_for_chunking &&
   1.129 -          new_obj->is_objArray() &&
   1.130 -          PSChunkLargeArrays) {
   1.131 -        // we'll chunk it
   1.132 -        oop* const masked_o = mask_chunked_array_oop(o);
   1.133 -        push_depth(masked_o);
   1.134 -        TASKQUEUE_STATS_ONLY(++_arrays_chunked; ++_masked_pushes);
   1.135 -      } else {
   1.136 -        // we'll just push its contents
   1.137 -        new_obj->push_contents(this);
   1.138 -      }
   1.139 -    }  else {
   1.140 -      // We lost, someone else "owns" this object
   1.141 -      guarantee(o->is_forwarded(), "Object must be forwarded if the cas failed.");
   1.142 -
   1.143 -      // Try to deallocate the space.  If it was directly allocated we cannot
   1.144 -      // deallocate it, so we have to test.  If the deallocation fails,
   1.145 -      // overwrite with a filler object.
   1.146 -      if (new_obj_is_tenured) {
   1.147 -        if (!_old_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
   1.148 -          CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
   1.149 -        }
   1.150 -      } else if (!_young_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
   1.151 -        CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
   1.152 -      }
   1.153 -
   1.154 -      // don't update this before the unallocation!
   1.155 -      new_obj = o->forwardee();
   1.156 -    }
   1.157 -  } else {
   1.158 -    assert(o->is_forwarded(), "Sanity");
   1.159 -    new_obj = o->forwardee();
   1.160 -  }
   1.161 -
   1.162 -#ifdef DEBUG
   1.163 -  // This code must come after the CAS test, or it will print incorrect
   1.164 -  // information.
   1.165 -  if (TraceScavenge) {
   1.166 -    gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (" SIZE_FORMAT ")}",
   1.167 -       PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
   1.168 -       new_obj->blueprint()->internal_name(), o, new_obj, new_obj->size());
   1.169 -  }
   1.170 -#endif
   1.171 -
   1.172 -  return new_obj;
   1.173 -}
   1.174 -
   1.175  template <class T> void PSPromotionManager::process_array_chunk_work(
   1.176                                                   oop obj,
   1.177                                                   int start, int end) {

mercurial