1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)ageTable.cpp 1.36 07/05/05 17:05:33 JVM"
   3 #endif
   4 /*
   5  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  
  26  */
  27 
  28 /* Copyright 1992 Sun Microsystems, Inc. and Stanford University.
  29    See the LICENSE file for license information. */
  30 
  31 # include "incls/_precompiled.incl"
  32 # include "incls/_ageTable.cpp.incl"
  33 
  34 ageTable::ageTable(bool global) {
  35 
  36   clear();
  37 
  38   if (UsePerfData && global) {
  39 
  40     ResourceMark rm;
  41     EXCEPTION_MARK;
  42 
  43     const char* agetable_ns = "generation.0.agetable";
  44     const char* bytes_ns = PerfDataManager::name_space(agetable_ns, "bytes");
  45 
  46     for(int age = 0; age < table_size; age ++) {
  47       char age_name[10];
  48       jio_snprintf(age_name, sizeof(age_name), "%2.2d", age);
  49       const char* cname = PerfDataManager::counter_name(bytes_ns, age_name);
  50       _perf_sizes[age] = PerfDataManager::create_variable(SUN_GC, cname,
  51                                                           PerfData::U_Bytes,
  52                                                           CHECK);
  53     }
  54 
  55     const char* cname = PerfDataManager::counter_name(agetable_ns, "size");
  56     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None,
  57                                      table_size, CHECK);
  58   }
  59 }
  60 
  61 void ageTable::clear() {
  62   for (size_t* p = sizes; p < sizes + table_size; ++p) {
  63     *p = 0;
  64   }
  65 }
  66 
  67 void ageTable::merge(ageTable* subTable) {
  68   for (int i = 0; i < table_size; i++) {
  69     sizes[i]+= subTable->sizes[i];
  70   }
  71 }
  72 
  73 void ageTable::merge_par(ageTable* subTable) {
  74   for (int i = 0; i < table_size; i++) {
  75     Atomic::add_ptr(subTable->sizes[i], &sizes[i]);
  76   }
  77 }
  78 
  79 int ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
  80   size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
  81   size_t total = 0;
  82   int age = 1;
  83   assert(sizes[0] == 0, "no objects with age zero should be recorded");
  84   while (age < table_size) {
  85     total += sizes[age];
  86     // check if including objects of age 'age' made us pass the desired
  87     // size, if so 'age' is the new threshold
  88     if (total > desired_survivor_size) break;
  89     age++;
  90   }
  91   int result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
  92 
  93   if (PrintTenuringDistribution || UsePerfData) {
  94 
  95     if (PrintTenuringDistribution) {
  96       gclog_or_tty->cr();
  97       gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %d (max %d)",
  98         desired_survivor_size*oopSize, result, MaxTenuringThreshold);
  99     }
 100 
 101     total = 0;
 102     age = 1;
 103     while (age < table_size) {
 104       total += sizes[age];
 105       if (sizes[age] > 0) {
 106         if (PrintTenuringDistribution) {
 107           gclog_or_tty->print_cr("- age %3d: %10ld bytes, %10ld total",
 108             age, sizes[age]*oopSize, total*oopSize);
 109         }
 110       }
 111       if (UsePerfData) {
 112         _perf_sizes[age]->set_value(sizes[age]*oopSize);
 113       }
 114       age++;
 115     }
 116     if (UsePerfData) {
 117       SharedHeap* sh = SharedHeap::heap();
 118       CollectorPolicy* policy = sh->collector_policy();
 119       GCPolicyCounters* gc_counters = policy->counters();
 120       gc_counters->tenuring_threshold()->set_value(result);
 121       gc_counters->desired_survivor_size()->set_value(
 122         desired_survivor_size*oopSize);
 123     }
 124   }
 125 
 126   return result;
 127 }