src/share/vm/code/codeCache.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/code/codeCache.hpp	Thu Nov  3 14:16:21 2016
--- new/src/share/vm/code/codeCache.hpp	Thu Nov  3 14:16:21 2016

*** 24,33 **** --- 24,34 ---- #ifndef SHARE_VM_CODE_CODECACHE_HPP #define SHARE_VM_CODE_CODECACHE_HPP #include "code/codeBlob.hpp" + #include "code/codeCacheExtensions.hpp" #include "code/nmethod.hpp" #include "memory/allocation.hpp" #include "memory/heap.hpp" #include "oops/instanceKlass.hpp" #include "oops/oopsHierarchy.hpp"
*** 75,91 **** --- 76,93 ---- class KlassDepChange; class CodeCache : AllStatic { friend class VMStructs; friend class JVMCIVMStructs; ! friend class NMethodIterator; friend class CompiledMethodIterator; ! template <class T, class Filter> friend class CodeBlobIterator; friend class WhiteBox; friend class CodeCacheLoader; private: // CodeHeaps of the cache static GrowableArray<CodeHeap*>* _heaps; + static GrowableArray<CodeHeap*>* _compiled_heaps; + static GrowableArray<CodeHeap*>* _nmethod_heaps; static address _low_bound; // Lower bound of CodeHeap addresses static address _high_bound; // Upper bound of CodeHeap addresses static int _number_of_nmethods_with_dependencies; // Total number of nmethods with dependencies static bool _needs_cache_clean; // True if inline caches of the nmethods needs to be flushed
*** 108,139 **** --- 110,151 ---- static ReservedCodeSpace reserve_heap_memory(size_t size); // Reserves one continuous chunk of memory for the CodeHeaps // Iteration static CodeBlob* first_blob(CodeHeap* heap); // Returns the first CodeBlob on the given CodeHeap static CodeBlob* first_blob(int code_blob_type); // Returns the first CodeBlob of the given type ! static CodeBlob* next_blob(CodeHeap* heap, CodeBlob* cb); // Returns the first alive CodeBlob on the given CodeHeap static CodeBlob* next_blob(CodeBlob* cb); // Returns the next CodeBlob of the given type succeeding the given CodeBlob ! static CodeBlob* next_blob(CodeHeap* heap, CodeBlob* cb); // Returns the next CodeBlob on the given CodeHeap static size_t bytes_allocated_in_freelists(); static int allocated_segments(); static size_t freelists_length(); static void set_scavenge_root_nmethods(nmethod* nm) { _scavenge_root_nmethods = nm; } static void prune_scavenge_root_nmethods(); static void unlink_scavenge_root_nmethod(nmethod* nm, nmethod* prev); + // Make private to prevent unsafe calls. Not all CodeBlob*'s are embedded in a CodeHeap. + static bool contains(CodeBlob *p) { fatal("don't call me!"); return false; } + public: // Initialization static void initialize(); + static int code_heap_compare(CodeHeap* const &lhs, CodeHeap* const &rhs); + + static void add_heap(CodeHeap* heap); + static const GrowableArray<CodeHeap*>* heaps() { return _heaps; } + static const GrowableArray<CodeHeap*>* compiled_heaps() { return _compiled_heaps; } + static const GrowableArray<CodeHeap*>* nmethod_heaps() { return _nmethod_heaps; } + // Allocation/administration static CodeBlob* allocate(int size, int code_blob_type, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled static int alignment_unit(); // guaranteed alignment of all CodeBlobs static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header) static void free(CodeBlob* cb); // frees a CodeBlob static bool contains(void *p); // returns whether p is included + static bool contains(nmethod* nm); // returns whether nm is included static void blobs_do(void f(CodeBlob* cb)); // iterates over all CodeBlobs static void blobs_do(CodeBlobClosure* f); // iterates over all CodeBlobs static void nmethods_do(void f(nmethod* nm)); // iterates over all nmethods static void metadata_do(void f(Metadata* m)); // iterates over metadata in alive nmethods
*** 190,199 **** --- 202,214 ---- static address low_bound() { return _low_bound; } static address low_bound(int code_blob_type); static address high_bound() { return _high_bound; } static address high_bound(int code_blob_type); + // Have to use far call instructions to call this pc. + static bool is_far_target(address pc); + // Profiling static size_t capacity(); static size_t unallocated_capacity(int code_blob_type); static size_t unallocated_capacity(); static size_t max_capacity();
*** 206,220 **** --- 221,245 ---- static void cleanup_inline_caches(); // Returns true if an own CodeHeap for the given CodeBlobType is available static bool heap_available(int code_blob_type); ! // Returns the CodeBlobType for the given nmethod ! // Returns the CodeBlobType for the given CompiledMethod static int get_code_blob_type(CompiledMethod* cm) { return get_code_heap(cm)->code_blob_type(); } + static bool code_blob_type_accepts_compiled(int type) { + bool result = type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled; + AOT_ONLY( result = result || type == CodeBlobType::AOT; ) + return result; + } + + static bool code_blob_type_accepts_nmethod(int type) { + return type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled; + } + // Returns the CodeBlobType for the given compilation level static int get_code_blob_type(int comp_level) { if (comp_level == CompLevel_none || comp_level == CompLevel_simple || comp_level == CompLevel_full_optimization) {
*** 262,391 **** --- 287,386 ---- } }; // Iterator to iterate over nmethods in the CodeCache. ! class NMethodIterator : public StackObj { ! template <class T, class Filter> class CodeBlobIterator : public StackObj { private: CodeBlob* _code_blob; // Current CodeBlob int _code_blob_type; // Refers to current CodeHeap + GrowableArrayIterator<CodeHeap*> _heap; + GrowableArrayIterator<CodeHeap*> _end; public: ! NMethodIterator() { ! initialize(NULL); // Set to NULL, initialized by first call to next() ! CodeBlobIterator(T* nm = NULL) { ! if (Filter::heaps() == NULL) { + return; + } + _heap = Filter::heaps()->begin(); + _end = Filter::heaps()->end(); + // If set to NULL, initialized by first call to next() + _code_blob = (CodeBlob*)nm; + if (nm != NULL) { + address start = nm->code_begin(); + while(!(*_heap)->contains(start)) { + ++_heap; + } + assert((*_heap)->contains(start), "match not found"); } NMethodIterator(nmethod* nm) { initialize(nm); } ! // Advance iterator to next nmethod ! // Advance iterator to next blob bool next() { assert_locked_or_safepoint(CodeCache_lock); assert(_code_blob_type < CodeBlobType::NumTypes, "end reached"); ! bool result = next_nmethod(); ! while (!result && (_code_blob_type < CodeBlobType::MethodProfiled)) { ! // Advance to next code heap if segmented code cache _code_blob_type++; ! result = next_nmethod(); ! bool result = next_blob(); ! while (!result && _heap != _end) { ! // Advance to next code heap of segmented code cache + if (++_heap == _end) { ! break; + } + result = next_blob(); } + return result; } ! // Advance iterator to next alive nmethod ! // Advance iterator to next alive blob bool next_alive() { bool result = next(); while(result && !_code_blob->is_alive()) { result = next(); } return result; } bool end() const { return _code_blob == NULL; } ! nmethod* method() const { return (nmethod*)_code_blob; } ! T* method() const { return (T*)_code_blob; } private: // Initialize iterator to given nmethod void initialize(nmethod* nm) { _code_blob = (CodeBlob*)nm; if (!SegmentedCodeCache) { // Iterate over all CodeBlobs _code_blob_type = CodeBlobType::All; } else if (nm != NULL) { _code_blob_type = CodeCache::get_code_blob_type(nm); } else { // Only iterate over method code heaps, starting with non-profiled _code_blob_type = CodeBlobType::MethodNonProfiled; } } ! // Advance iterator to the next nmethod in the current code heap ! bool next_nmethod() { ! // Advance iterator to the next blob in the current code heap ! bool next_blob() { + if (_heap == _end) { + return false; + } + CodeHeap *heap = *_heap; // Get first method CodeBlob if (_code_blob == NULL) { ! _code_blob = CodeCache::first_blob(_code_blob_type); ! _code_blob = CodeCache::first_blob(heap); if (_code_blob == NULL) { return false; ! } else if (_code_blob->is_nmethod()) { ! } else if (Filter::apply(_code_blob)) { return true; } } // Search for next method CodeBlob ! _code_blob = CodeCache::next_blob(heap, _code_blob); ! while (_code_blob != NULL && !_code_blob->is_nmethod()) { ! _code_blob = CodeCache::next_blob(_code_blob); ! while (_code_blob != NULL && !Filter::apply(_code_blob)) { ! _code_blob = CodeCache::next_blob(heap, _code_blob); } return _code_blob != NULL; } }; // Iterator to iterate over compiled methods in the CodeCache. class CompiledMethodIterator : public StackObj { private: CodeBlob* _code_blob; // Current CodeBlob int _code_blob_type; // Refers to current CodeHeap public: CompiledMethodIterator() { initialize(NULL); // Set to NULL, initialized by first call to next() } CompiledMethodIterator(CompiledMethod* cm) { initialize(cm); } // Advance iterator to next compiled method bool next() { assert_locked_or_safepoint(CodeCache_lock); ! assert(_code_blob_type < CodeBlobType::NumTypes, "end reached"); bool result = next_compiled_method(); while (!result && (_code_blob_type < CodeBlobType::MethodProfiled)) { // Advance to next code heap if segmented code cache _code_blob_type++; result = next_compiled_method(); } return result; } + struct CompiledMethodFilter { + static bool apply(CodeBlob* cb) { return cb->is_compiled(); } + static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::compiled_heaps(); } ! }; // Advance iterator to next alive compiled method bool next_alive() { bool result = next(); while(result && !_code_blob->is_alive()) { result = next(); } return result; } bool end() const { return _code_blob == NULL; } ! CompiledMethod* method() const { return (_code_blob != NULL) ? _code_blob->as_compiled_method() : NULL; } + struct NMethodFilter { ! static bool apply(CodeBlob* cb) { return cb->is_nmethod(); } + static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::nmethod_heaps(); } + }; private: // Initialize iterator to given compiled method void initialize(CompiledMethod* cm); // Advance iterator to the next compiled method in the current code heap ! bool next_compiled_method(); }; + typedef CodeBlobIterator<CompiledMethod, CompiledMethodFilter> CompiledMethodIterator; ! typedef CodeBlobIterator<nmethod, NMethodFilter> NMethodIterator; #endif // SHARE_VM_CODE_CODECACHE_HPP

src/share/vm/code/codeCache.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File