316 static int get_codemem_full_count(int code_blob_type) {
317 CodeHeap* heap = get_code_heap(code_blob_type);
318 return (heap != NULL) ? heap->full_count() : 0;
319 }
320
321 // CodeHeap State Analytics.
322 // interface methods for CodeHeap printing, called by CompileBroker
323 static void aggregate(outputStream *out, const char* granularity);
324 static void discard(outputStream *out);
325 static void print_usedSpace(outputStream *out);
326 static void print_freeSpace(outputStream *out);
327 static void print_count(outputStream *out);
328 static void print_space(outputStream *out);
329 static void print_age(outputStream *out);
330 static void print_names(outputStream *out);
331 };
332
333
334 // Iterator to iterate over nmethods in the CodeCache.
335 template <class T, class Filter> class CodeBlobIterator : public StackObj {
336 private:
337 CodeBlob* _code_blob; // Current CodeBlob
338 GrowableArrayIterator<CodeHeap*> _heap;
339 GrowableArrayIterator<CodeHeap*> _end;
340
341 public:
342 CodeBlobIterator(T* nm = NULL) {
343 if (Filter::heaps() == NULL) {
344 return;
345 }
346 _heap = Filter::heaps()->begin();
347 _end = Filter::heaps()->end();
348 // If set to NULL, initialized by first call to next()
349 _code_blob = (CodeBlob*)nm;
350 if (nm != NULL) {
351 while(!(*_heap)->contains_blob(_code_blob)) {
352 ++_heap;
353 }
354 assert((*_heap)->contains_blob(_code_blob), "match not found");
355 }
356 }
357
358 // Advance iterator to next blob
359 bool next() {
360 assert_locked_or_safepoint(CodeCache_lock);
361
362 bool result = next_blob();
363 while (!result && _heap != _end) {
364 // Advance to next code heap of segmented code cache
365 if (++_heap == _end) {
366 break;
367 }
368 result = next_blob();
369 }
370
371 return result;
372 }
373
374 // Advance iterator to next alive blob
375 bool next_alive() {
376 bool result = next();
377 while(result && !_code_blob->is_alive()) {
378 result = next();
379 }
380 return result;
381 }
382
383 bool end() const { return _code_blob == NULL; }
384 T* method() const { return (T*)_code_blob; }
385
386 private:
387
388 // Advance iterator to the next blob in the current code heap
389 bool next_blob() {
390 if (_heap == _end) {
391 return false;
392 }
393 CodeHeap *heap = *_heap;
394 // Get first method CodeBlob
395 if (_code_blob == NULL) {
396 _code_blob = CodeCache::first_blob(heap);
397 if (_code_blob == NULL) {
398 return false;
399 } else if (Filter::apply(_code_blob)) {
400 return true;
401 }
402 }
403 // Search for next method CodeBlob
404 _code_blob = CodeCache::next_blob(heap, _code_blob);
405 while (_code_blob != NULL && !Filter::apply(_code_blob)) {
406 _code_blob = CodeCache::next_blob(heap, _code_blob);
407 }
408 return _code_blob != NULL;
409 }
410 };
411
412
413 struct CompiledMethodFilter {
414 static bool apply(CodeBlob* cb) { return cb->is_compiled(); }
415 static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::compiled_heaps(); }
416 };
417
418
419 struct NMethodFilter {
420 static bool apply(CodeBlob* cb) { return cb->is_nmethod(); }
421 static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::nmethod_heaps(); }
422 };
423
424
425 typedef CodeBlobIterator<CompiledMethod, CompiledMethodFilter> CompiledMethodIterator;
426 typedef CodeBlobIterator<nmethod, NMethodFilter> NMethodIterator;
427
428 #endif // SHARE_VM_CODE_CODECACHE_HPP
|
316 static int get_codemem_full_count(int code_blob_type) {
317 CodeHeap* heap = get_code_heap(code_blob_type);
318 return (heap != NULL) ? heap->full_count() : 0;
319 }
320
321 // CodeHeap State Analytics.
322 // interface methods for CodeHeap printing, called by CompileBroker
323 static void aggregate(outputStream *out, const char* granularity);
324 static void discard(outputStream *out);
325 static void print_usedSpace(outputStream *out);
326 static void print_freeSpace(outputStream *out);
327 static void print_count(outputStream *out);
328 static void print_space(outputStream *out);
329 static void print_age(outputStream *out);
330 static void print_names(outputStream *out);
331 };
332
333
334 // Iterator to iterate over nmethods in the CodeCache.
335 template <class T, class Filter> class CodeBlobIterator : public StackObj {
336 public:
337 enum LivenessFilter { all_blobs, only_alive, only_alive_and_not_unloading };
338
339 private:
340 CodeBlob* _code_blob; // Current CodeBlob
341 GrowableArrayIterator<CodeHeap*> _heap;
342 GrowableArrayIterator<CodeHeap*> _end;
343 bool _only_alive;
344 bool _only_not_unloading;
345
346 public:
347 CodeBlobIterator(LivenessFilter filter, T* nm = NULL)
348 : _only_alive(filter == only_alive || filter == only_alive_and_not_unloading),
349 _only_not_unloading(filter == only_alive_and_not_unloading)
350 {
351 if (Filter::heaps() == NULL) {
352 return;
353 }
354 _heap = Filter::heaps()->begin();
355 _end = Filter::heaps()->end();
356 // If set to NULL, initialized by first call to next()
357 _code_blob = (CodeBlob*)nm;
358 if (nm != NULL) {
359 while(!(*_heap)->contains_blob(_code_blob)) {
360 ++_heap;
361 }
362 assert((*_heap)->contains_blob(_code_blob), "match not found");
363 }
364 }
365
366 CodeBlobIterator(const CodeBlobIterator& other)
367 : _code_blob(other._code_blob),
368 _heap(other._heap),
369 _end(other._end),
370 _only_alive(other._only_alive),
371 _only_not_unloading(other._only_not_unloading)
372 { }
373
374 // Advance iterator to next blob
375 bool next() {
376 assert_locked_or_safepoint(CodeCache_lock);
377
378 for (;;) {
379 // Walk through heaps as required
380 if (!next_blob()) {
381 if (_heap == _end) {
382 return false;
383 }
384 ++_heap;
385 continue;
386 }
387
388 // Filter is_alive as required
389 if (_only_alive && !_code_blob->is_alive()) {
390 continue;
391 }
392
393 // Filter is_unloading as required
394 if (_only_not_unloading) {
395 CompiledMethod* cm = _code_blob->as_compiled_method_or_null();
396 if (cm != NULL && cm->is_unloading()) {
397 continue;
398 }
399 }
400
401 return true;
402 }
403 }
404
405 bool end() const { return _code_blob == NULL; }
406 T* method() const { return (T*)_code_blob; }
407
408 private:
409
410 // Advance iterator to the next blob in the current code heap
411 bool next_blob() {
412 if (_heap == _end) {
413 return false;
414 }
415 CodeHeap *heap = *_heap;
416 // Get first method CodeBlob
417 if (_code_blob == NULL) {
418 _code_blob = CodeCache::first_blob(heap);
419 if (_code_blob == NULL) {
420 return false;
421 } else if (Filter::apply(_code_blob)) {
422 return true;
423 }
424 }
425 // Search for next method CodeBlob
426 _code_blob = CodeCache::next_blob(heap, _code_blob);
427 while (_code_blob != NULL && !Filter::apply(_code_blob)) {
428 _code_blob = CodeCache::next_blob(heap, _code_blob);
429 }
430 return _code_blob != NULL;
431 }
432 };
433
434
435 struct CompiledMethodFilter {
436 static bool apply(CodeBlob* cb) { return cb->is_compiled(); }
437 static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::compiled_heaps(); }
438 };
439
440
441 struct NMethodFilter {
442 static bool apply(CodeBlob* cb) { return cb->is_nmethod(); }
443 static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::nmethod_heaps(); }
444 };
445
446 typedef CodeBlobIterator<CompiledMethod, CompiledMethodFilter> CompiledMethodIterator;
447 typedef CodeBlobIterator<nmethod, NMethodFilter> NMethodIterator;
448
449 #endif // SHARE_VM_CODE_CODECACHE_HPP
|