src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp

changeset 1580
e018e6884bd8
parent 704
850fdf70db2b
child 1844
cff162798819
     1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp	Wed Dec 16 15:12:51 2009 -0800
     1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp	Wed Dec 23 09:23:54 2009 -0800
     1.3 @@ -62,12 +62,13 @@
     1.4    tl->link_head(tc);
     1.5    tl->link_tail(tc);
     1.6    tl->set_count(1);
     1.7 -  tl->init_statistics();
     1.8 +  tl->init_statistics(true /* split_birth */);
     1.9    tl->setParent(NULL);
    1.10    tl->setLeft(NULL);
    1.11    tl->setRight(NULL);
    1.12    return tl;
    1.13  }
    1.14 +
    1.15  TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) {
    1.16    TreeChunk* tc = (TreeChunk*) addr;
    1.17    assert(size >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk");
    1.18 @@ -267,6 +268,31 @@
    1.19    return retTC;
    1.20  }
    1.21  
    1.22 +// Returns the block with the largest heap address amongst
    1.23 +// those in the list for this size; potentially slow and expensive,
    1.24 +// use with caution!
    1.25 +TreeChunk* TreeList::largest_address() {
    1.26 +  guarantee(head() != NULL, "The head of the list cannot be NULL");
    1.27 +  FreeChunk* fc = head()->next();
    1.28 +  TreeChunk* retTC;
    1.29 +  if (fc == NULL) {
    1.30 +    retTC = head_as_TreeChunk();
    1.31 +  } else {
    1.32 +    // walk down the list and return the one with the highest
    1.33 +    // heap address among chunks of this size.
    1.34 +    FreeChunk* last = fc;
    1.35 +    while (fc->next() != NULL) {
    1.36 +      if ((HeapWord*)last < (HeapWord*)fc) {
    1.37 +        last = fc;
    1.38 +      }
    1.39 +      fc = fc->next();
    1.40 +    }
    1.41 +    retTC = TreeChunk::as_TreeChunk(last);
    1.42 +  }
    1.43 +  assert(retTC->list() == this, "Wrong type of chunk.");
    1.44 +  return retTC;
    1.45 +}
    1.46 +
    1.47  BinaryTreeDictionary::BinaryTreeDictionary(MemRegion mr, bool splay):
    1.48    _splay(splay)
    1.49  {
    1.50 @@ -379,7 +405,7 @@
    1.51              break;
    1.52            }
    1.53            // The evm code reset the hint of the candidate as
    1.54 -          // at an interrim point.  Why?  Seems like this leaves
    1.55 +          // at an interim point.  Why?  Seems like this leaves
    1.56            // the hint pointing to a list that didn't work.
    1.57            // curTL->set_hint(hintTL->size());
    1.58          }
    1.59 @@ -436,7 +462,7 @@
    1.60    TreeList *curTL = root();
    1.61    if (curTL != NULL) {
    1.62      while(curTL->right() != NULL) curTL = curTL->right();
    1.63 -    return curTL->first_available();
    1.64 +    return curTL->largest_address();
    1.65    } else {
    1.66      return NULL;
    1.67    }
    1.68 @@ -664,7 +690,7 @@
    1.69      }
    1.70    }
    1.71    TreeChunk* tc = TreeChunk::as_TreeChunk(fc);
    1.72 -  // This chunk is being returned to the binary try.  It's embedded
    1.73 +  // This chunk is being returned to the binary tree.  Its embedded
    1.74    // TreeList should be unused at this point.
    1.75    tc->initialize();
    1.76    if (curTL != NULL) {          // exact match
    1.77 @@ -807,6 +833,8 @@
    1.78  }
    1.79  
    1.80  bool BinaryTreeDictionary::coalDictOverPopulated(size_t size) {
    1.81 +  if (FLSAlwaysCoalesceLarge) return true;
    1.82 +
    1.83    TreeList* list_of_size = findList(size);
    1.84    // None of requested size implies overpopulated.
    1.85    return list_of_size == NULL || list_of_size->coalDesired() <= 0 ||
    1.86 @@ -854,17 +882,20 @@
    1.87    double _percentage;
    1.88    float _inter_sweep_current;
    1.89    float _inter_sweep_estimate;
    1.90 +  float _intra_sweep_estimate;
    1.91  
    1.92   public:
    1.93    BeginSweepClosure(double p, float inter_sweep_current,
    1.94 -                              float inter_sweep_estimate) :
    1.95 +                              float inter_sweep_estimate,
    1.96 +                              float intra_sweep_estimate) :
    1.97     _percentage(p),
    1.98     _inter_sweep_current(inter_sweep_current),
    1.99 -   _inter_sweep_estimate(inter_sweep_estimate) { }
   1.100 +   _inter_sweep_estimate(inter_sweep_estimate),
   1.101 +   _intra_sweep_estimate(intra_sweep_estimate) { }
   1.102  
   1.103    void do_list(FreeList* fl) {
   1.104      double coalSurplusPercent = _percentage;
   1.105 -    fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate);
   1.106 +    fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate, _intra_sweep_estimate);
   1.107      fl->set_coalDesired((ssize_t)((double)fl->desired() * coalSurplusPercent));
   1.108      fl->set_beforeSweep(fl->count());
   1.109      fl->set_bfrSurp(fl->surplus());
   1.110 @@ -939,9 +970,10 @@
   1.111  }
   1.112  
   1.113  void BinaryTreeDictionary::beginSweepDictCensus(double coalSurplusPercent,
   1.114 -  float inter_sweep_current, float inter_sweep_estimate) {
   1.115 +  float inter_sweep_current, float inter_sweep_estimate, float intra_sweep_estimate) {
   1.116    BeginSweepClosure bsc(coalSurplusPercent, inter_sweep_current,
   1.117 -                                            inter_sweep_estimate);
   1.118 +                                            inter_sweep_estimate,
   1.119 +                                            intra_sweep_estimate);
   1.120    bsc.do_tree(root());
   1.121  }
   1.122  
   1.123 @@ -1077,13 +1109,13 @@
   1.124  // Print census information - counts, births, deaths, etc.
   1.125  // for each list in the tree.  Also print some summary
   1.126  // information.
   1.127 -class printTreeCensusClosure : public AscendTreeCensusClosure {
   1.128 +class PrintTreeCensusClosure : public AscendTreeCensusClosure {
   1.129    int _print_line;
   1.130    size_t _totalFree;
   1.131    FreeList _total;
   1.132  
   1.133   public:
   1.134 -  printTreeCensusClosure() {
   1.135 +  PrintTreeCensusClosure() {
   1.136      _print_line = 0;
   1.137      _totalFree = 0;
   1.138    }
   1.139 @@ -1113,7 +1145,7 @@
   1.140  
   1.141    gclog_or_tty->print("\nBinaryTree\n");
   1.142    FreeList::print_labels_on(gclog_or_tty, "size");
   1.143 -  printTreeCensusClosure ptc;
   1.144 +  PrintTreeCensusClosure ptc;
   1.145    ptc.do_tree(root());
   1.146  
   1.147    FreeList* total = ptc.total();
   1.148 @@ -1130,6 +1162,38 @@
   1.149               /(total->desired() != 0 ? (double)total->desired() : 1.0));
   1.150  }
   1.151  
   1.152 +class PrintFreeListsClosure : public AscendTreeCensusClosure {
   1.153 +  outputStream* _st;
   1.154 +  int _print_line;
   1.155 +
   1.156 + public:
   1.157 +  PrintFreeListsClosure(outputStream* st) {
   1.158 +    _st = st;
   1.159 +    _print_line = 0;
   1.160 +  }
   1.161 +  void do_list(FreeList* fl) {
   1.162 +    if (++_print_line >= 40) {
   1.163 +      FreeList::print_labels_on(_st, "size");
   1.164 +      _print_line = 0;
   1.165 +    }
   1.166 +    fl->print_on(gclog_or_tty);
   1.167 +    size_t sz = fl->size();
   1.168 +    for (FreeChunk* fc = fl->head(); fc != NULL;
   1.169 +         fc = fc->next()) {
   1.170 +      _st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ")  %s",
   1.171 +                    fc, (HeapWord*)fc + sz,
   1.172 +                    fc->cantCoalesce() ? "\t CC" : "");
   1.173 +    }
   1.174 +  }
   1.175 +};
   1.176 +
   1.177 +void BinaryTreeDictionary::print_free_lists(outputStream* st) const {
   1.178 +
   1.179 +  FreeList::print_labels_on(st, "size");
   1.180 +  PrintFreeListsClosure pflc(st);
   1.181 +  pflc.do_tree(root());
   1.182 +}
   1.183 +
   1.184  // Verify the following tree invariants:
   1.185  // . _root has no parent
   1.186  // . parent and child point to each other

mercurial