Path: blob/master/src/hotspot/share/code/codeCache.hpp
40930 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_CODE_CODECACHE_HPP25#define SHARE_CODE_CODECACHE_HPP2627#include "code/codeBlob.hpp"28#include "code/nmethod.hpp"29#include "gc/shared/gcBehaviours.hpp"30#include "memory/allocation.hpp"31#include "memory/heap.hpp"32#include "oops/instanceKlass.hpp"33#include "oops/oopsHierarchy.hpp"34#include "runtime/mutexLocker.hpp"3536// The CodeCache implements the code cache for various pieces of generated37// code, e.g., compiled java methods, runtime stubs, transition frames, etc.38// The entries in the CodeCache are all CodeBlob's.3940// -- Implementation --41// The CodeCache consists of one or more CodeHeaps, each of which contains42// CodeBlobs of a specific CodeBlobType. Currently heaps for the following43// types are available:44// - Non-nmethods: Non-nmethods like Buffers, Adapters and Runtime Stubs45// - Profiled nmethods: nmethods that are profiled, i.e., those46// executed at level 2 or 347// - Non-Profiled nmethods: nmethods that are not profiled, i.e., those48// executed at level 1 or 4 and native methods49// - All: Used for code of all types if code cache segmentation is disabled.50//51// In the rare case of the non-nmethod code heap getting full, non-nmethod code52// will be stored in the non-profiled code heap as a fallback solution.53//54// Depending on the availability of compilers and compilation mode there55// may be fewer heaps. The size of the code heaps depends on the values of56// ReservedCodeCacheSize, NonProfiledCodeHeapSize and ProfiledCodeHeapSize57// (see CodeCache::heap_available(..) and CodeCache::initialize_heaps(..)58// for details).59//60// Code cache segmentation is controlled by the flag SegmentedCodeCache.61// If turned off, all code types are stored in a single code heap. By default62// code cache segmentation is turned on if tiered mode is enabled and63// ReservedCodeCacheSize >= 240 MB.64//65// All methods of the CodeCache accepting a CodeBlobType only apply to66// CodeBlobs of the given type. For example, iteration over the67// CodeBlobs of a specific type can be done by using CodeCache::first_blob(..)68// and CodeCache::next_blob(..) and providing the corresponding CodeBlobType.69//70// IMPORTANT: If you add new CodeHeaps to the code cache or change the71// existing ones, make sure to adapt the dtrace scripts (jhelper.d) for72// Solaris and BSD.7374class ExceptionCache;75class KlassDepChange;76class OopClosure;77class ShenandoahParallelCodeHeapIterator;7879class CodeCache : AllStatic {80friend class VMStructs;81friend class JVMCIVMStructs;82template <class T, class Filter> friend class CodeBlobIterator;83friend class WhiteBox;84friend class CodeCacheLoader;85friend class ShenandoahParallelCodeHeapIterator;86private:87// CodeHeaps of the cache88static GrowableArray<CodeHeap*>* _heaps;89static GrowableArray<CodeHeap*>* _compiled_heaps;90static GrowableArray<CodeHeap*>* _nmethod_heaps;91static GrowableArray<CodeHeap*>* _allocable_heaps;9293static address _low_bound; // Lower bound of CodeHeap addresses94static address _high_bound; // Upper bound of CodeHeap addresses95static int _number_of_nmethods_with_dependencies; // Total number of nmethods with dependencies96static uint8_t _unloading_cycle; // Global state for recognizing old nmethods that need to be unloaded9798static ExceptionCache* volatile _exception_cache_purge_list;99100// CodeHeap management101static void initialize_heaps(); // Initializes the CodeHeaps102// Check the code heap sizes set by the user via command line103static void check_heap_sizes(size_t non_nmethod_size, size_t profiled_size, size_t non_profiled_size, size_t cache_size, bool all_set);104// Creates a new heap with the given name and size, containing CodeBlobs of the given type105static void add_heap(ReservedSpace rs, const char* name, int code_blob_type);106static CodeHeap* get_code_heap_containing(void* p); // Returns the CodeHeap containing the given pointer, or NULL107static CodeHeap* get_code_heap(const CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob108static CodeHeap* get_code_heap(int code_blob_type); // Returns the CodeHeap for the given CodeBlobType109// Returns the name of the VM option to set the size of the corresponding CodeHeap110static const char* get_code_heap_flag_name(int code_blob_type);111static ReservedCodeSpace reserve_heap_memory(size_t size); // Reserves one continuous chunk of memory for the CodeHeaps112113// Iteration114static CodeBlob* first_blob(CodeHeap* heap); // Returns the first CodeBlob on the given CodeHeap115static CodeBlob* first_blob(int code_blob_type); // Returns the first CodeBlob of the given type116static CodeBlob* next_blob(CodeHeap* heap, CodeBlob* cb); // Returns the next CodeBlob on the given CodeHeap117118static size_t bytes_allocated_in_freelists();119static int allocated_segments();120static size_t freelists_length();121122// Make private to prevent unsafe calls. Not all CodeBlob*'s are embedded in a CodeHeap.123static bool contains(CodeBlob *p) { fatal("don't call me!"); return false; }124125public:126// Initialization127static void initialize();128static size_t page_size(bool aligned = true, size_t min_pages = 1); // Returns the page size used by the CodeCache129130static int code_heap_compare(CodeHeap* const &lhs, CodeHeap* const &rhs);131132static void add_heap(CodeHeap* heap);133static const GrowableArray<CodeHeap*>* heaps() { return _heaps; }134static const GrowableArray<CodeHeap*>* compiled_heaps() { return _compiled_heaps; }135static const GrowableArray<CodeHeap*>* nmethod_heaps() { return _nmethod_heaps; }136137// Allocation/administration138static CodeBlob* allocate(int size, int code_blob_type, bool handle_alloc_failure = true, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob139static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled140static int alignment_unit(); // guaranteed alignment of all CodeBlobs141static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)142static void free(CodeBlob* cb); // frees a CodeBlob143static void free_unused_tail(CodeBlob* cb, size_t used); // frees the unused tail of a CodeBlob (only used by TemplateInterpreter::initialize())144static bool contains(void *p); // returns whether p is included145static bool contains(nmethod* nm); // returns whether nm is included146static void blobs_do(void f(CodeBlob* cb)); // iterates over all CodeBlobs147static void blobs_do(CodeBlobClosure* f); // iterates over all CodeBlobs148static void nmethods_do(void f(nmethod* nm)); // iterates over all nmethods149static void metadata_do(MetadataClosure* f); // iterates over metadata in alive nmethods150151// Lookup152static CodeBlob* find_blob(void* start); // Returns the CodeBlob containing the given address153static CodeBlob* find_blob_unsafe(void* start); // Same as find_blob but does not fail if looking up a zombie method154static nmethod* find_nmethod(void* start); // Returns the nmethod containing the given address155static CompiledMethod* find_compiled(void* start);156157static int blob_count(); // Returns the total number of CodeBlobs in the cache158static int blob_count(int code_blob_type);159static int adapter_count(); // Returns the total number of Adapters in the cache160static int adapter_count(int code_blob_type);161static int nmethod_count(); // Returns the total number of nmethods in the cache162static int nmethod_count(int code_blob_type);163164// GC support165static void verify_oops();166// If any oops are not marked this method unloads (i.e., breaks root links167// to) any unmarked codeBlobs in the cache. Sets "marked_for_unloading"168// to "true" iff some code got unloaded.169// "unloading_occurred" controls whether metadata should be cleaned because of class unloading.170class UnloadingScope: StackObj {171ClosureIsUnloadingBehaviour _is_unloading_behaviour;172IsUnloadingBehaviour* _saved_behaviour;173174public:175UnloadingScope(BoolObjectClosure* is_alive);176~UnloadingScope();177};178179static void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);180static uint8_t unloading_cycle() { return _unloading_cycle; }181static void increment_unloading_cycle();182static void release_exception_cache(ExceptionCache* entry);183static void purge_exception_caches();184185// Printing/debugging186static void print(); // prints summary187static void print_internals();188static void print_memory_overhead();189static void verify(); // verifies the code cache190static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;191static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage192static void log_state(outputStream* st);193LINUX_ONLY(static void write_perf_map();)194static const char* get_code_heap_name(int code_blob_type) { return (heap_available(code_blob_type) ? get_code_heap(code_blob_type)->name() : "Unused"); }195static void report_codemem_full(int code_blob_type, bool print);196197// Dcmd (Diagnostic commands)198static void print_codelist(outputStream* st);199static void print_layout(outputStream* st);200201// The full limits of the codeCache202static address low_bound() { return _low_bound; }203static address low_bound(int code_blob_type);204static address high_bound() { return _high_bound; }205static address high_bound(int code_blob_type);206207// Profiling208static size_t capacity();209static size_t unallocated_capacity(int code_blob_type);210static size_t unallocated_capacity();211static size_t max_capacity();212213static double reverse_free_ratio(int code_blob_type);214215static void clear_inline_caches(); // clear all inline caches216static void cleanup_inline_caches(); // clean unloaded/zombie nmethods from inline caches217218// Returns true if an own CodeHeap for the given CodeBlobType is available219static bool heap_available(int code_blob_type);220221// Returns the CodeBlobType for the given CompiledMethod222static int get_code_blob_type(CompiledMethod* cm) {223return get_code_heap(cm)->code_blob_type();224}225226static bool code_blob_type_accepts_compiled(int type) {227bool result = type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled;228return result;229}230231static bool code_blob_type_accepts_nmethod(int type) {232return type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled;233}234235static bool code_blob_type_accepts_allocable(int type) {236return type <= CodeBlobType::All;237}238239240// Returns the CodeBlobType for the given compilation level241static int get_code_blob_type(int comp_level) {242if (comp_level == CompLevel_none ||243comp_level == CompLevel_simple ||244comp_level == CompLevel_full_optimization) {245// Non profiled methods246return CodeBlobType::MethodNonProfiled;247} else if (comp_level == CompLevel_limited_profile ||248comp_level == CompLevel_full_profile) {249// Profiled methods250return CodeBlobType::MethodProfiled;251}252ShouldNotReachHere();253return 0;254}255256static void verify_clean_inline_caches();257static void verify_icholder_relocations();258259// Deoptimization260private:261static int mark_for_deoptimization(KlassDepChange& changes);262263public:264static void mark_all_nmethods_for_deoptimization();265static int mark_for_deoptimization(Method* dependee);266static void make_marked_nmethods_not_entrant();267268// Flushing and deoptimization269static void flush_dependents_on(InstanceKlass* dependee);270271// RedefineClasses support272// Flushing and deoptimization in case of evolution273static void mark_for_evol_deoptimization(InstanceKlass* dependee);274static int mark_dependents_for_evol_deoptimization();275static void mark_all_nmethods_for_evol_deoptimization();276static void flush_evol_dependents();277static void old_nmethods_do(MetadataClosure* f) NOT_JVMTI_RETURN;278static void unregister_old_nmethod(CompiledMethod* c) NOT_JVMTI_RETURN;279280// Support for fullspeed debugging281static void flush_dependents_on_method(const methodHandle& dependee);282283// tells how many nmethods have dependencies284static int number_of_nmethods_with_dependencies();285286static int get_codemem_full_count(int code_blob_type) {287CodeHeap* heap = get_code_heap(code_blob_type);288return (heap != NULL) ? heap->full_count() : 0;289}290291// CodeHeap State Analytics.292// interface methods for CodeHeap printing, called by CompileBroker293static void aggregate(outputStream *out, size_t granularity);294static void discard(outputStream *out);295static void print_usedSpace(outputStream *out);296static void print_freeSpace(outputStream *out);297static void print_count(outputStream *out);298static void print_space(outputStream *out);299static void print_age(outputStream *out);300static void print_names(outputStream *out);301};302303304// Iterator to iterate over nmethods in the CodeCache.305template <class T, class Filter> class CodeBlobIterator : public StackObj {306public:307enum LivenessFilter { all_blobs, only_alive, only_alive_and_not_unloading };308309private:310CodeBlob* _code_blob; // Current CodeBlob311GrowableArrayIterator<CodeHeap*> _heap;312GrowableArrayIterator<CodeHeap*> _end;313bool _only_alive;314bool _only_not_unloading;315316public:317CodeBlobIterator(LivenessFilter filter, T* nm = NULL)318: _only_alive(filter == only_alive || filter == only_alive_and_not_unloading),319_only_not_unloading(filter == only_alive_and_not_unloading)320{321if (Filter::heaps() == NULL) {322return;323}324_heap = Filter::heaps()->begin();325_end = Filter::heaps()->end();326// If set to NULL, initialized by first call to next()327_code_blob = (CodeBlob*)nm;328if (nm != NULL) {329while(!(*_heap)->contains_blob(_code_blob)) {330++_heap;331}332assert((*_heap)->contains_blob(_code_blob), "match not found");333}334}335336// Advance iterator to next blob337bool next() {338assert_locked_or_safepoint(CodeCache_lock);339340for (;;) {341// Walk through heaps as required342if (!next_blob()) {343if (_heap == _end) {344return false;345}346++_heap;347continue;348}349350// Filter is_alive as required351if (_only_alive && !_code_blob->is_alive()) {352continue;353}354355// Filter is_unloading as required356if (_only_not_unloading) {357CompiledMethod* cm = _code_blob->as_compiled_method_or_null();358if (cm != NULL && cm->is_unloading()) {359continue;360}361}362363return true;364}365}366367bool end() const { return _code_blob == NULL; }368T* method() const { return (T*)_code_blob; }369370private:371372// Advance iterator to the next blob in the current code heap373bool next_blob() {374if (_heap == _end) {375return false;376}377CodeHeap *heap = *_heap;378// Get first method CodeBlob379if (_code_blob == NULL) {380_code_blob = CodeCache::first_blob(heap);381if (_code_blob == NULL) {382return false;383} else if (Filter::apply(_code_blob)) {384return true;385}386}387// Search for next method CodeBlob388_code_blob = CodeCache::next_blob(heap, _code_blob);389while (_code_blob != NULL && !Filter::apply(_code_blob)) {390_code_blob = CodeCache::next_blob(heap, _code_blob);391}392return _code_blob != NULL;393}394};395396397struct CompiledMethodFilter {398static bool apply(CodeBlob* cb) { return cb->is_compiled(); }399static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::compiled_heaps(); }400};401402403struct NMethodFilter {404static bool apply(CodeBlob* cb) { return cb->is_nmethod(); }405static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::nmethod_heaps(); }406};407408struct AllCodeBlobsFilter {409static bool apply(CodeBlob* cb) { return true; }410static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::heaps(); }411};412413typedef CodeBlobIterator<CompiledMethod, CompiledMethodFilter> CompiledMethodIterator;414typedef CodeBlobIterator<nmethod, NMethodFilter> NMethodIterator;415typedef CodeBlobIterator<CodeBlob, AllCodeBlobsFilter> AllCodeBlobsIterator;416417#endif // SHARE_CODE_CODECACHE_HPP418419420