00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_sweeper.cpp.incl"
00026 # include <math.h>
00027
00028
00029
00030
00031
00032 Sweeper* Sweeper::_head = NULL;
00033 int Sweeper::sweep_seconds = 0;
00034 bool Sweeper::_is_running = false;
00035 methodOop Sweeper::_active_method = NULL;
00036 nmethod* Sweeper::_active_nmethod = NULL;
00037
00038 void Sweeper::print_all() {
00039 for (Sweeper* n = head(); n; n = n->next())
00040 n->print();
00041 }
00042
00043 bool Sweeper::register_active_frame(frame fr) {
00044 if (fr.is_interpreted_frame()) {
00045 _active_method = fr.method();
00046 if (_active_method == NULL) return NULL;
00047 return true;
00048 } else if (fr.is_compiled_frame()) {
00049 _active_nmethod = findNMethod(fr.pc());
00050 return true;
00051 }
00052 return false;
00053 }
00054
00055 void Sweeper::clear_active_frame() {
00056 _active_method = NULL;
00057 _active_nmethod = NULL;
00058 }
00059
00060 void Sweeper::step_all() {
00061 _is_running = true;
00062 ResourceMark rm;
00063 for (Sweeper* n = head(); n; n = n->next())
00064 n->step();
00065 sweep_seconds++;
00066 _is_running = false;
00067 }
00068
00069 Sweeper::Sweeper() {
00070 _is_active = false;
00071 _sweep_start = sweep_seconds;
00072 }
00073
00074 void Sweeper::add(Sweeper* sweeper) {
00075 sweeper->_next = head();
00076 _head = sweeper;
00077 }
00078
00079 void Sweeper::step() {
00080 if (interval() == 0) return;
00081
00082 if (!is_active() && (sweep_seconds - _sweep_start) >= interval()) {
00083 _sweep_start = sweep_seconds;
00084 activate();
00085 }
00086 if (is_active()) task();
00087 }
00088
00089 void Sweeper::print() const {
00090 std->print_cr("%s", name());
00091 }
00092
00093 void Sweeper::activate() {
00094 _is_active = true;
00095 LOG_EVENT1("Activating %s", name());
00096 }
00097
00098 void Sweeper::deactivate() {
00099 _is_active = false;
00100 LOG_EVENT1("Deactivating %s", name());
00101 }
00102
00103
00104
00105 void HeapSweeper::activate() {
00106 mark = Universe::old_gen.bottom_mark();
00107 Sweeper::activate();
00108 }
00109
00110 void HeapSweeper::task() {}
00111
00112
00113
00114 inline void CodeSweeper::updateInterval() {
00115 if (oldHalfLifeTime != CounterHalfLifeTime) {
00116 oldHalfLifeTime = CounterHalfLifeTime;
00117 CodeSweeperInterval = 4;
00118 fractionPerTask = 8;
00119 const double log2 = 0.69314718055995;
00120 decayFactor = exp(log2 * CodeSweeperInterval * fractionPerTask / CounterHalfLifeTime);
00121 if (PrintCodeSweep) std->print("*method sweep: decay factor %f\n", decayFactor);
00122 }
00123 }
00124
00125
00126 int CodeSweeper::interval() const {
00127 ((CodeSweeper*)this)->updateInterval();
00128 return CodeSweeperInterval;
00129 }
00130
00131
00132
00133
00134 void MethodSweeper::method_task(methodOop method) {
00135 if (method != Sweeper::active_method()) {
00136 if (method->invocation_count() > 0) {
00137 method->decay_invocation_count(decayFactor);
00138 }
00139 method->cleanup_inline_caches();
00140 } else {
00141
00142 set_excluded_method(Sweeper::active_method());
00143 }
00144 }
00145
00146 int MethodSweeper::method_dict_task(objArrayOop methods) {
00147 int length = methods->length();
00148 for (int index = 1; index <= length; index++) {
00149 methodOop method = methodOop(methods->obj_at(index));
00150 assert(method->is_method(), "just checking");
00151 method_task(method);
00152 }
00153 return length;
00154 }
00155
00156 int MethodSweeper::klass_task(klassOop klass) {
00157 int result = 0;
00158 Klass* k = klass->klass_part();
00159
00160 result += method_dict_task(k->methods());
00161 result += method_dict_task(klass->klass()->klass_part()->methods());
00162 if (k->is_named_class()) {
00163
00164 result += method_dict_task(k->mixin()->methods());
00165 result += method_dict_task(klass->klass()->klass_part()->mixin()->methods());
00166 }
00167
00168 if (!k->has_superKlass()) return result;
00169 if (k->superKlass()->klass_part()->is_named_class()) return result;
00170
00171
00172 result += klass_task(k->superKlass());
00173 return result;
00174 }
00175
00176 void MethodSweeper::task() {
00177
00178 if (excluded_method()) {
00179 methodOop m = excluded_method();
00180 set_excluded_method(NULL);
00181 method_task(m);
00182 }
00183
00184 objArrayOop array = Universe::systemDictionaryObj();
00185 int length = array->length();
00186 int number_of_entries = length / fractionPerTask;
00187 if (PrintCodeSweep) std->print("*method sweep: %d entries...", number_of_entries);
00188 TraceTime t("MethodSweep ", PrintCodeSweep);
00189
00190 int end = (index + number_of_entries);
00191 if (end > length)
00192 end = length;
00193
00194 int begin = index;
00195 int result = 0;
00196
00197 for (; index <= end; index++) {
00198 associationOop assoc = associationOop(array->obj_at(index));
00199 assert(assoc->is_association(), "just checking");
00200 if (assoc->is_constant() && assoc->value()->is_klass()) {
00201 int result = klass_task(klassOop(assoc->value()));
00202 }
00203 }
00204 LOG_EVENT3("MethodSweeper task [%d, %d] #%d", begin, end, result);
00205
00206 if (index > length) deactivate();
00207 }
00208
00209 void MethodSweeper::activate() {
00210 index = 1;
00211 Sweeper::activate();
00212 }
00213
00214
00215
00216 void ZoneSweeper::nmethod_task(nmethod* nm) {
00217 if (nm != Sweeper::active_nmethod()) {
00218 nm->sweeper_step(decayFactor);
00219 } else {
00220
00221 set_excluded_nmethod(Sweeper::active_nmethod());
00222 }
00223 }
00224
00225 void ZoneSweeper::task() {
00226
00227 if (excluded_nmethod()) {
00228 nmethod* nm = excluded_nmethod();
00229 set_excluded_nmethod(NULL);
00230 nmethod_task(nm);
00231 }
00232
00233
00234
00235 int total = Universe::code->numberOfNMethods();
00236 int todo = total / fractionPerTask;
00237 if (PrintCodeSweep) std->print("*zone sweep: %d of %d entries...", todo, total);
00238 TraceTime t("ZoneSweep ", PrintCodeSweep);
00239
00240 for (int index = 0; index < todo; index++) {
00241 if (next == NULL) {
00242 deactivate();
00243 break;
00244 }
00245 nmethod_task(next);
00246 next = Universe::code->next_nm(next);
00247 }
00248
00249 if (UseNMethodAging) {
00250 for (nmethod* nm = Universe::code->first_nm(); nm; nm = Universe::code->next_nm(nm)) {
00251 nm->incrementAge();
00252 }
00253 }
00254 }
00255
00256 void ZoneSweeper::activate() {
00257 if (Universe::code->numberOfNMethods() > 0) {
00258 next = Universe::code->first_nm();
00259 _excluded_nmethod = NULL;
00260 Sweeper::activate();
00261 } else {
00262 deactivate();
00263 }
00264 }
00265
00266
00267 class SweeperTask : public PeriodicTask {
00268 private:
00269 int counter;
00270 public:
00271 SweeperTask() : PeriodicTask(100) {
00272 counter = 0;
00273 }
00274
00275 void task() {
00276
00277 if (DeltaProcess::is_idle()) return;
00278 if (++counter > 10) {
00279 if (processSemaphore) return;
00280 if (last_Delta_fp) return;
00281
00282 if (Sweeper::register_active_frame(DeltaProcess::active()->profile_top_frame())) {
00283 Sweeper::step_all();
00284 Sweeper::clear_active_frame();
00285 counter -= 10;
00286 }
00287 }
00288 }
00289 };
00290
00291 MethodSweeper* methodSweeper;
00292
00293 void sweeper_init() {
00294
00295 Sweeper::add(new ZoneSweeper());
00296 Sweeper::add(methodSweeper = new MethodSweeper());
00297
00298 if (SweeperUseTimer) {
00299 SweeperTask* t = new SweeperTask;
00300 t->enroll();
00301 }
00302 }