47 // we have to wait until the next marking phase has completed. If a not-entrant |
47 // we have to wait until the next marking phase has completed. If a not-entrant |
48 // nmethod was NOT marked as active, it can be converted to 'zombie' state. To safely |
48 // nmethod was NOT marked as active, it can be converted to 'zombie' state. To safely |
49 // remove the nmethod, all inline caches (IC) that point to the the nmethod must be |
49 // remove the nmethod, all inline caches (IC) that point to the the nmethod must be |
50 // cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's |
50 // cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's |
51 // state change happens during separate sweeps. It may take at least 3 sweeps before an |
51 // state change happens during separate sweeps. It may take at least 3 sweeps before an |
52 // nmethod's space is freed. Sweeping is currently done by compiler threads between |
52 // nmethod's space is freed. |
53 // compilations or at least each 5 sec (NmethodSweepCheckInterval) when the code cache |
|
54 // is full. |
|
55 |
53 |
56 class NMethodSweeper : public AllStatic { |
54 class NMethodSweeper : public AllStatic { |
57 static long _traversals; // Stack scan count, also sweep ID. |
55 static long _traversals; // Stack scan count, also sweep ID. |
58 static long _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache |
56 static long _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache |
59 static long _time_counter; // Virtual time used to periodically invoke sweeper |
57 static long _time_counter; // Virtual time used to periodically invoke sweeper |
62 static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache |
60 static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache |
63 static int _flushed_count; // Nof. nmethods flushed in current sweep |
61 static int _flushed_count; // Nof. nmethods flushed in current sweep |
64 static int _zombified_count; // Nof. nmethods made zombie in current sweep |
62 static int _zombified_count; // Nof. nmethods made zombie in current sweep |
65 static int _marked_for_reclamation_count; // Nof. nmethods marked for reclaim in current sweep |
63 static int _marked_for_reclamation_count; // Nof. nmethods marked for reclaim in current sweep |
66 |
64 |
67 static volatile int _sweep_fractions_left; // Nof. invocations left until we are completed with this pass |
|
68 static volatile int _sweep_started; // Flag to control conc sweeper |
65 static volatile int _sweep_started; // Flag to control conc sweeper |
69 static volatile bool _should_sweep; // Indicates if we should invoke the sweeper |
66 static volatile bool _should_sweep; // Indicates if we should invoke the sweeper |
70 static volatile int _bytes_changed; // Counts the total nmethod size if the nmethod changed from: |
67 static volatile int _bytes_changed; // Counts the total nmethod size if the nmethod changed from: |
71 // 1) alive -> not_entrant |
68 // 1) alive -> not_entrant |
72 // 2) not_entrant -> zombie |
69 // 2) not_entrant -> zombie |
83 static Tickspan _peak_sweep_fraction_time; // Peak time sweeping one fraction |
80 static Tickspan _peak_sweep_fraction_time; // Peak time sweeping one fraction |
84 |
81 |
85 static int process_nmethod(nmethod *nm); |
82 static int process_nmethod(nmethod *nm); |
86 static void release_nmethod(nmethod* nm); |
83 static void release_nmethod(nmethod* nm); |
87 |
84 |
88 static bool sweep_in_progress(); |
85 static void init_sweeper_log() NOT_DEBUG_RETURN; |
|
86 static bool wait_for_stack_scanning(); |
89 static void sweep_code_cache(); |
87 static void sweep_code_cache(); |
|
88 static void handle_safepoint_request(); |
|
89 static void do_stack_scanning(); |
|
90 static void possibly_sweep(); |
90 |
91 |
91 public: |
92 public: |
92 static long traversal_count() { return _traversals; } |
93 static long traversal_count() { return _traversals; } |
93 static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } |
94 static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } |
94 static const Tickspan total_time_sweeping() { return _total_time_sweeping; } |
95 static const Tickspan total_time_sweeping() { return _total_time_sweeping; } |
104 static void report_events(int id, address entry); |
105 static void report_events(int id, address entry); |
105 static void report_events(); |
106 static void report_events(); |
106 #endif |
107 #endif |
107 |
108 |
108 static void mark_active_nmethods(); // Invoked at the end of each safepoint |
109 static void mark_active_nmethods(); // Invoked at the end of each safepoint |
109 static void possibly_sweep(); // Compiler threads call this to sweep |
110 static void sweeper_loop(); |
|
111 static void notify(int code_blob_type); // Possibly start the sweeper thread. |
110 |
112 |
111 static int hotness_counter_reset_val(); |
113 static int hotness_counter_reset_val(); |
112 static void report_state_change(nmethod* nm); |
114 static void report_state_change(nmethod* nm); |
113 static void possibly_enable_sweeper(); |
115 static void possibly_enable_sweeper(); |
114 static void possibly_flush(nmethod* nm); |
116 static void possibly_flush(nmethod* nm); |