Mercurial > hg > truffle
comparison src/share/vm/code/codeCache.cpp @ 10408:836a62f43af9
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 19 Jun 2013 10:45:56 +0200 |
parents | ebb32c4589f3 f2110083203d |
children | f22cbff51c12 |
comparison
equal
deleted
inserted
replaced
10086:e0fb8a213650 | 10408:836a62f43af9 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
43 #include "runtime/arguments.hpp" | 43 #include "runtime/arguments.hpp" |
44 #include "runtime/icache.hpp" | 44 #include "runtime/icache.hpp" |
45 #include "runtime/java.hpp" | 45 #include "runtime/java.hpp" |
46 #include "runtime/mutexLocker.hpp" | 46 #include "runtime/mutexLocker.hpp" |
47 #include "services/memoryService.hpp" | 47 #include "services/memoryService.hpp" |
48 #include "trace/tracing.hpp" | |
48 #include "utilities/xmlstream.hpp" | 49 #include "utilities/xmlstream.hpp" |
49 | 50 |
50 // Helper class for printing in CodeCache | 51 // Helper class for printing in CodeCache |
51 | 52 |
52 class CodeBlob_sizes { | 53 class CodeBlob_sizes { |
112 code_size += cb->code_size(); | 113 code_size += cb->code_size(); |
113 } | 114 } |
114 } | 115 } |
115 }; | 116 }; |
116 | 117 |
117 | |
118 // CodeCache implementation | 118 // CodeCache implementation |
119 | 119 |
120 CodeHeap * CodeCache::_heap = new CodeHeap(); | 120 CodeHeap * CodeCache::_heap = new CodeHeap(); |
121 int CodeCache::_number_of_blobs = 0; | 121 int CodeCache::_number_of_blobs = 0; |
122 int CodeCache::_number_of_adapters = 0; | 122 int CodeCache::_number_of_adapters = 0; |
124 int CodeCache::_number_of_nmethods_with_dependencies = 0; | 124 int CodeCache::_number_of_nmethods_with_dependencies = 0; |
125 bool CodeCache::_needs_cache_clean = false; | 125 bool CodeCache::_needs_cache_clean = false; |
126 nmethod* CodeCache::_scavenge_root_nmethods = NULL; | 126 nmethod* CodeCache::_scavenge_root_nmethods = NULL; |
127 nmethod* CodeCache::_saved_nmethods = NULL; | 127 nmethod* CodeCache::_saved_nmethods = NULL; |
128 | 128 |
129 int CodeCache::_codemem_full_count = 0; | |
129 | 130 |
130 CodeBlob* CodeCache::first() { | 131 CodeBlob* CodeCache::first() { |
131 assert_locked_or_safepoint(CodeCache_lock); | 132 assert_locked_or_safepoint(CodeCache_lock); |
132 return (CodeBlob*)_heap->first(); | 133 return (CodeBlob*)_heap->first(); |
133 } | 134 } |
170 return (nmethod*)cb; | 171 return (nmethod*)cb; |
171 } | 172 } |
172 | 173 |
173 static size_t maxCodeCacheUsed = 0; | 174 static size_t maxCodeCacheUsed = 0; |
174 | 175 |
175 CodeBlob* CodeCache::allocate(int size) { | 176 CodeBlob* CodeCache::allocate(int size, bool is_critical) { |
176 // Do not seize the CodeCache lock here--if the caller has not | 177 // Do not seize the CodeCache lock here--if the caller has not |
177 // already done so, we are going to lose bigtime, since the code | 178 // already done so, we are going to lose bigtime, since the code |
178 // cache will contain a garbage CodeBlob until the caller can | 179 // cache will contain a garbage CodeBlob until the caller can |
179 // run the constructor for the CodeBlob subclass he is busy | 180 // run the constructor for the CodeBlob subclass he is busy |
180 // instantiating. | 181 // instantiating. |
181 guarantee(size >= 0, "allocation request must be reasonable"); | 182 guarantee(size >= 0, "allocation request must be reasonable"); |
182 assert_locked_or_safepoint(CodeCache_lock); | 183 assert_locked_or_safepoint(CodeCache_lock); |
183 CodeBlob* cb = NULL; | 184 CodeBlob* cb = NULL; |
184 _number_of_blobs++; | 185 _number_of_blobs++; |
185 while (true) { | 186 while (true) { |
186 cb = (CodeBlob*)_heap->allocate(size); | 187 cb = (CodeBlob*)_heap->allocate(size, is_critical); |
187 if (cb != NULL) break; | 188 if (cb != NULL) break; |
188 if (!_heap->expand_by(CodeCacheExpansionSize)) { | 189 if (!_heap->expand_by(CodeCacheExpansionSize)) { |
189 // Expansion failed | 190 // Expansion failed |
190 return NULL; | 191 return NULL; |
191 } | 192 } |
192 if (PrintCodeCacheExtension) { | 193 if (PrintCodeCacheExtension) { |
193 ResourceMark rm; | 194 ResourceMark rm; |
194 tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%d bytes)", | 195 tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%d bytes)", |
195 (intptr_t)_heap->begin(), (intptr_t)_heap->end(), | 196 (intptr_t)_heap->low_boundary(), (intptr_t)_heap->high(), |
196 (address)_heap->end() - (address)_heap->begin()); | 197 (address)_heap->high() - (address)_heap->low_boundary()); |
197 } | 198 } |
198 } | 199 } |
199 maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - | 200 maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - |
200 (address)_heap->low_boundary()) - unallocated_capacity()); | 201 (address)_heap->low_boundary()) - unallocated_capacity()); |
201 verify_if_often(); | 202 verify_if_often(); |
470 if (call_f) f_or_null->do_code_blob(cb); | 471 if (call_f) f_or_null->do_code_blob(cb); |
471 } | 472 } |
472 } | 473 } |
473 #endif //PRODUCT | 474 #endif //PRODUCT |
474 | 475 |
475 | 476 /** |
476 nmethod* CodeCache::find_and_remove_saved_code(Method* m) { | 477 * Remove and return nmethod from the saved code list in order to reanimate it. |
478 */ | |
479 nmethod* CodeCache::reanimate_saved_code(Method* m) { | |
477 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | 480 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
478 nmethod* saved = _saved_nmethods; | 481 nmethod* saved = _saved_nmethods; |
479 nmethod* prev = NULL; | 482 nmethod* prev = NULL; |
480 while (saved != NULL) { | 483 while (saved != NULL) { |
481 if (saved->is_in_use() && saved->method() == m) { | 484 if (saved->is_in_use() && saved->method() == m) { |
486 } | 489 } |
487 assert(saved->is_speculatively_disconnected(), "shouldn't call for other nmethods"); | 490 assert(saved->is_speculatively_disconnected(), "shouldn't call for other nmethods"); |
488 saved->set_speculatively_disconnected(false); | 491 saved->set_speculatively_disconnected(false); |
489 saved->set_saved_nmethod_link(NULL); | 492 saved->set_saved_nmethod_link(NULL); |
490 if (PrintMethodFlushing) { | 493 if (PrintMethodFlushing) { |
491 saved->print_on(tty, " ### nmethod is reconnected\n"); | 494 saved->print_on(tty, " ### nmethod is reconnected"); |
492 } | 495 } |
493 if (LogCompilation && (xtty != NULL)) { | 496 if (LogCompilation && (xtty != NULL)) { |
494 ttyLocker ttyl; | 497 ttyLocker ttyl; |
495 xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id()); | 498 xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id()); |
496 xtty->method(m); | 499 xtty->method(m); |
503 saved = saved->saved_nmethod_link(); | 506 saved = saved->saved_nmethod_link(); |
504 } | 507 } |
505 return NULL; | 508 return NULL; |
506 } | 509 } |
507 | 510 |
511 /** | |
512 * Remove nmethod from the saved code list in order to discard it permanently | |
513 */ | |
508 void CodeCache::remove_saved_code(nmethod* nm) { | 514 void CodeCache::remove_saved_code(nmethod* nm) { |
509 // For conc swpr this will be called with CodeCache_lock taken by caller | 515 // For conc swpr this will be called with CodeCache_lock taken by caller |
510 assert_locked_or_safepoint(CodeCache_lock); | 516 assert_locked_or_safepoint(CodeCache_lock); |
511 assert(nm->is_speculatively_disconnected(), "shouldn't call for other nmethods"); | 517 assert(nm->is_speculatively_disconnected(), "shouldn't call for other nmethods"); |
512 nmethod* saved = _saved_nmethods; | 518 nmethod* saved = _saved_nmethods; |
536 assert_locked_or_safepoint(CodeCache_lock); | 542 assert_locked_or_safepoint(CodeCache_lock); |
537 assert(nm->is_in_use() && !nm->is_speculatively_disconnected(), "should only disconnect live nmethods"); | 543 assert(nm->is_in_use() && !nm->is_speculatively_disconnected(), "should only disconnect live nmethods"); |
538 nm->set_saved_nmethod_link(_saved_nmethods); | 544 nm->set_saved_nmethod_link(_saved_nmethods); |
539 _saved_nmethods = nm; | 545 _saved_nmethods = nm; |
540 if (PrintMethodFlushing) { | 546 if (PrintMethodFlushing) { |
541 nm->print_on(tty, " ### nmethod is speculatively disconnected\n"); | 547 nm->print_on(tty, " ### nmethod is speculatively disconnected"); |
542 } | 548 } |
543 if (LogCompilation && (xtty != NULL)) { | 549 if (LogCompilation && (xtty != NULL)) { |
544 ttyLocker ttyl; | 550 ttyLocker ttyl; |
545 xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id()); | 551 xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id()); |
546 xtty->method(nm->method()); | 552 xtty->method(nm->method()); |
615 } | 621 } |
616 | 622 |
617 | 623 |
618 address CodeCache::first_address() { | 624 address CodeCache::first_address() { |
619 assert_locked_or_safepoint(CodeCache_lock); | 625 assert_locked_or_safepoint(CodeCache_lock); |
620 return (address)_heap->begin(); | 626 return (address)_heap->low_boundary(); |
621 } | 627 } |
622 | 628 |
623 | 629 |
624 address CodeCache::last_address() { | 630 address CodeCache::last_address() { |
625 assert_locked_or_safepoint(CodeCache_lock); | 631 assert_locked_or_safepoint(CodeCache_lock); |
626 return (address)_heap->end(); | 632 return (address)_heap->high(); |
627 } | 633 } |
628 | 634 |
635 /** | |
636 * Returns the reverse free ratio. E.g., if 25% (1/4) of the code cache | |
637 * is free, reverse_free_ratio() returns 4. | |
638 */ | |
639 double CodeCache::reverse_free_ratio() { | |
640 double unallocated_capacity = (double)(CodeCache::unallocated_capacity() - CodeCacheMinimumFreeSpace); | |
641 double max_capacity = (double)CodeCache::max_capacity(); | |
642 return max_capacity / unallocated_capacity; | |
643 } | |
629 | 644 |
630 void icache_init(); | 645 void icache_init(); |
631 | 646 |
632 void CodeCache::initialize() { | 647 void CodeCache::initialize() { |
633 assert(CodeCacheSegmentSize >= (uintx)CodeEntryAlignment, "CodeCacheSegmentSize must be large enough to align entry points"); | 648 assert(CodeCacheSegmentSize >= (uintx)CodeEntryAlignment, "CodeCacheSegmentSize must be large enough to align entry points"); |
819 | 834 |
820 void CodeCache::verify() { | 835 void CodeCache::verify() { |
821 _heap->verify(); | 836 _heap->verify(); |
822 FOR_ALL_ALIVE_BLOBS(p) { | 837 FOR_ALL_ALIVE_BLOBS(p) { |
823 p->verify(); | 838 p->verify(); |
839 } | |
840 } | |
841 | |
842 void CodeCache::report_codemem_full() { | |
843 _codemem_full_count++; | |
844 EventCodeCacheFull event; | |
845 if (event.should_commit()) { | |
846 event.set_startAddress((u8)low_bound()); | |
847 event.set_commitedTopAddress((u8)high()); | |
848 event.set_reservedTopAddress((u8)high_bound()); | |
849 event.set_entryCount(nof_blobs()); | |
850 event.set_methodCount(nof_nmethods()); | |
851 event.set_adaptorCount(nof_adapters()); | |
852 event.set_unallocatedCapacity(unallocated_capacity()/K); | |
853 event.set_fullCount(_codemem_full_count); | |
854 event.commit(); | |
824 } | 855 } |
825 } | 856 } |
826 | 857 |
827 //------------------------------------------------------------------------------------------------ | 858 //------------------------------------------------------------------------------------------------ |
828 // Non-product version | 859 // Non-product version |
1003 } | 1034 } |
1004 | 1035 |
1005 void CodeCache::print_summary(outputStream* st, bool detailed) { | 1036 void CodeCache::print_summary(outputStream* st, bool detailed) { |
1006 size_t total = (_heap->high_boundary() - _heap->low_boundary()); | 1037 size_t total = (_heap->high_boundary() - _heap->low_boundary()); |
1007 st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT | 1038 st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT |
1008 "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT | 1039 "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT "Kb", |
1009 "Kb max_free_chunk=" SIZE_FORMAT "Kb", | |
1010 total/K, (total - unallocated_capacity())/K, | 1040 total/K, (total - unallocated_capacity())/K, |
1011 maxCodeCacheUsed/K, unallocated_capacity()/K, largest_free_block()/K); | 1041 maxCodeCacheUsed/K, unallocated_capacity()/K); |
1012 | 1042 |
1013 if (detailed) { | 1043 if (detailed) { |
1014 st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", | 1044 st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", |
1015 _heap->low_boundary(), | 1045 _heap->low_boundary(), |
1016 _heap->high(), | 1046 _heap->high(), |
1025 } | 1055 } |
1026 } | 1056 } |
1027 | 1057 |
1028 void CodeCache::log_state(outputStream* st) { | 1058 void CodeCache::log_state(outputStream* st) { |
1029 st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" | 1059 st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" |
1030 " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'" | 1060 " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
1031 " largest_free_block='" SIZE_FORMAT "'", | |
1032 nof_blobs(), nof_nmethods(), nof_adapters(), | 1061 nof_blobs(), nof_nmethods(), nof_adapters(), |
1033 unallocated_capacity(), largest_free_block()); | 1062 unallocated_capacity()); |
1034 } | 1063 } |
1035 | 1064 |
1036 size_t CodeCache::largest_free_block() { | |
1037 // This is called both with and without CodeCache_lock held so | |
1038 // handle both cases. | |
1039 if (CodeCache_lock->owned_by_self()) { | |
1040 return _heap->largest_free_block(); | |
1041 } else { | |
1042 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
1043 return _heap->largest_free_block(); | |
1044 } | |
1045 } |