1.1 --- a/src/share/vm/runtime/sweeper.hpp Fri Sep 27 08:39:19 2013 +0200 1.2 +++ b/src/share/vm/runtime/sweeper.hpp Fri Sep 27 10:50:55 2013 +0200 1.3 @@ -27,8 +27,30 @@ 1.4 1.5 // An NmethodSweeper is an incremental cleaner for: 1.6 // - cleanup inline caches 1.7 -// - reclamation of unreferences zombie nmethods 1.8 -// 1.9 +// - reclamation of nmethods 1.10 +// Removing nmethods from the code cache includes two operations 1.11 +// 1) mark active nmethods 1.12 +// Is done in 'mark_active_nmethods()'. This function is called at a 1.13 +// safepoint and marks all nmethods that are active on a thread's stack. 1.14 +// 2) sweep nmethods 1.15 +// Is done in sweep_code_cache(). This function is the only place in the 1.16 +// sweeper where memory is reclaimed. Note that sweep_code_cache() is not 1.17 +// called at a safepoint. However, sweep_code_cache() stops executing if 1.18 +// another thread requests a safepoint. Consequently, 'mark_active_nmethods()' 1.19 +// and sweep_code_cache() cannot execute at the same time. 1.20 +// To reclaim memory, nmethods are first marked as 'not-entrant'. Methods can 1.21 +// be made not-entrant by (i) the sweeper, (ii) deoptimization, (iii) dependency 1.22 +// invalidation, and (iv) being replaced be a different method version (tiered 1.23 +// compilation). Not-entrant nmethod cannot be called by Java threads, but they 1.24 +// can still be active on the stack. To ensure that active nmethod are not reclaimed, 1.25 +// we have to wait until the next marking phase has completed. If a not-entrant 1.26 +// nmethod was NOT marked as active, it can be converted to 'zombie' state. To safely 1.27 +// remove the nmethod, all inline caches (IC) that point to the the nmethod must be 1.28 +// cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's 1.29 +// state change happens during separate sweeps. It may take at least 3 sweeps before an 1.30 +// nmethod's space is freed. Sweeping is currently done by compiler threads between 1.31 +// compilations or at least each 5 sec (NmethodSweepCheckInterval) when the code cache 1.32 +// is full. 1.33 1.34 class NMethodSweeper : public AllStatic { 1.35 static long _traversals; // Stack scan count, also sweep ID. 1.36 @@ -41,46 +63,38 @@ 1.37 static volatile int _invocations; // No. of invocations left until we are completed with this pass 1.38 static volatile int _sweep_started; // Flag to control conc sweeper 1.39 1.40 - //The following are reset in scan_stacks and synchronized by the safepoint 1.41 - static bool _resweep; // Indicates that a change has happend and we want another sweep, 1.42 - // always checked and reset at a safepoint so memory will be in sync. 1.43 - static int _locked_seen; // Number of locked nmethods encountered during the scan 1.44 + //The following are reset in mark_active_nmethods and synchronized by the safepoint 1.45 + static bool _request_mark_phase; // Indicates that a change has happend and we need another mark pahse, 1.46 + // always checked and reset at a safepoint so memory will be in sync. 1.47 + static int _locked_seen; // Number of locked nmethods encountered during the scan 1.48 static int _not_entrant_seen_on_stack; // Number of not entrant nmethod were are still on stack 1.49 - static jint _flush_token; // token that guards method flushing, making sure it is executed only once. 1.50 - 1.51 - // These are set during a flush, a VM-operation 1.52 - static long _last_flush_traversal_id; // trav number at last flush unloading 1.53 - static jlong _last_full_flush_time; // timestamp of last emergency unloading 1.54 - 1.55 - // These are synchronized by the _sweep_started token 1.56 - static int _highest_marked; // highest compile id dumped at last emergency unloading 1.57 - static int _dead_compile_ids; // number of compile ids that where not in the cache last flush 1.58 1.59 // Stat counters 1.60 - static int _number_of_flushes; // Total of full traversals caused by full cache 1.61 static int _total_nof_methods_reclaimed; // Accumulated nof methods flushed 1.62 static jlong _total_time_sweeping; // Accumulated time sweeping 1.63 static jlong _total_time_this_sweep; // Total time this sweep 1.64 static jlong _peak_sweep_time; // Peak time for a full sweep 1.65 static jlong _peak_sweep_fraction_time; // Peak time sweeping one fraction 1.66 - static jlong _total_disconnect_time; // Total time cleaning code mem 1.67 - static jlong _peak_disconnect_time; // Peak time cleaning code mem 1.68 1.69 - static void process_nmethod(nmethod *nm); 1.70 + static int process_nmethod(nmethod *nm); 1.71 static void release_nmethod(nmethod* nm); 1.72 1.73 - static void log_sweep(const char* msg, const char* format = NULL, ...); 1.74 static bool sweep_in_progress(); 1.75 + static void sweep_code_cache(); 1.76 + static void request_nmethod_marking() { _request_mark_phase = true; } 1.77 + static void reset_nmethod_marking() { _request_mark_phase = false; } 1.78 + static bool need_marking_phase() { return _request_mark_phase; } 1.79 + 1.80 + static int _hotness_counter_reset_val; 1.81 1.82 public: 1.83 static long traversal_count() { return _traversals; } 1.84 - static int number_of_flushes() { return _number_of_flushes; } 1.85 static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } 1.86 static jlong total_time_sweeping() { return _total_time_sweeping; } 1.87 static jlong peak_sweep_time() { return _peak_sweep_time; } 1.88 static jlong peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } 1.89 - static jlong total_disconnect_time() { return _total_disconnect_time; } 1.90 - static jlong peak_disconnect_time() { return _peak_disconnect_time; } 1.91 + static void log_sweep(const char* msg, const char* format = NULL, ...); 1.92 + 1.93 1.94 #ifdef ASSERT 1.95 static bool is_sweeping(nmethod* which) { return _current == which; } 1.96 @@ -90,19 +104,18 @@ 1.97 static void report_events(); 1.98 #endif 1.99 1.100 - static void scan_stacks(); // Invoked at the end of each safepoint 1.101 - static void sweep_code_cache(); // Concurrent part of sweep job 1.102 - static void possibly_sweep(); // Compiler threads call this to sweep 1.103 + static void mark_active_nmethods(); // Invoked at the end of each safepoint 1.104 + static void possibly_sweep(); // Compiler threads call this to sweep 1.105 1.106 - static void notify(nmethod* nm) { 1.107 + static int sort_nmethods_by_hotness(nmethod** nm1, nmethod** nm2); 1.108 + static int hotness_counter_reset_val(); 1.109 + 1.110 + static void notify() { 1.111 // Request a new sweep of the code cache from the beginning. No 1.112 // need to synchronize the setting of this flag since it only 1.113 // changes to false at safepoint so we can never overwrite it with false. 1.114 - _resweep = true; 1.115 + request_nmethod_marking(); 1.116 } 1.117 - 1.118 - static void handle_full_code_cache(bool is_full); // Called by compilers who fail to allocate 1.119 - static void speculative_disconnect_nmethods(bool was_full); // Called by vm op to deal with alloc failure 1.120 }; 1.121 1.122 #endif // SHARE_VM_RUNTIME_SWEEPER_HPP