Mercurial > hg > truffle
comparison src/share/vm/code/codeCache.cpp @ 10114:a7fb14888912
8006952: Slow VM due to excessive code cache freelist iteration
Summary: Remove continous free block requirement
Reviewed-by: kvn
author | neliasso |
---|---|
date | Thu, 11 Apr 2013 13:57:44 +0200 |
parents | 9deda4d8e126 |
children | 0cfa93c2fcc4 |
comparison
equal
deleted
inserted
replaced
10113:4b2eebe03f93 | 10114:a7fb14888912 |
---|---|
170 return (nmethod*)cb; | 170 return (nmethod*)cb; |
171 } | 171 } |
172 | 172 |
173 static size_t maxCodeCacheUsed = 0; | 173 static size_t maxCodeCacheUsed = 0; |
174 | 174 |
175 CodeBlob* CodeCache::allocate(int size) { | 175 CodeBlob* CodeCache::allocate(int size, bool is_critical) { |
176 // Do not seize the CodeCache lock here--if the caller has not | 176 // 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 | 177 // already done so, we are going to lose bigtime, since the code |
178 // cache will contain a garbage CodeBlob until the caller can | 178 // cache will contain a garbage CodeBlob until the caller can |
179 // run the constructor for the CodeBlob subclass he is busy | 179 // run the constructor for the CodeBlob subclass he is busy |
180 // instantiating. | 180 // instantiating. |
181 guarantee(size >= 0, "allocation request must be reasonable"); | 181 guarantee(size >= 0, "allocation request must be reasonable"); |
182 assert_locked_or_safepoint(CodeCache_lock); | 182 assert_locked_or_safepoint(CodeCache_lock); |
183 CodeBlob* cb = NULL; | 183 CodeBlob* cb = NULL; |
184 _number_of_blobs++; | 184 _number_of_blobs++; |
185 while (true) { | 185 while (true) { |
186 cb = (CodeBlob*)_heap->allocate(size); | 186 cb = (CodeBlob*)_heap->allocate(size, is_critical); |
187 if (cb != NULL) break; | 187 if (cb != NULL) break; |
188 if (!_heap->expand_by(CodeCacheExpansionSize)) { | 188 if (!_heap->expand_by(CodeCacheExpansionSize)) { |
189 // Expansion failed | 189 // Expansion failed |
190 return NULL; | 190 return NULL; |
191 } | 191 } |
192 if (PrintCodeCacheExtension) { | 192 if (PrintCodeCacheExtension) { |
193 ResourceMark rm; | 193 ResourceMark rm; |
194 tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%d bytes)", | 194 tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%d bytes)", |
195 (intptr_t)_heap->begin(), (intptr_t)_heap->end(), | 195 (intptr_t)_heap->low_boundary(), (intptr_t)_heap->high(), |
196 (address)_heap->end() - (address)_heap->begin()); | 196 (address)_heap->high() - (address)_heap->low_boundary()); |
197 } | 197 } |
198 } | 198 } |
199 maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - | 199 maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - |
200 (address)_heap->low_boundary()) - unallocated_capacity()); | 200 (address)_heap->low_boundary()) - unallocated_capacity()); |
201 verify_if_often(); | 201 verify_if_often(); |
606 } | 606 } |
607 | 607 |
608 | 608 |
609 address CodeCache::first_address() { | 609 address CodeCache::first_address() { |
610 assert_locked_or_safepoint(CodeCache_lock); | 610 assert_locked_or_safepoint(CodeCache_lock); |
611 return (address)_heap->begin(); | 611 return (address)_heap->low_boundary(); |
612 } | 612 } |
613 | 613 |
614 | 614 |
615 address CodeCache::last_address() { | 615 address CodeCache::last_address() { |
616 assert_locked_or_safepoint(CodeCache_lock); | 616 assert_locked_or_safepoint(CodeCache_lock); |
617 return (address)_heap->end(); | 617 return (address)_heap->high(); |
618 } | 618 } |
619 | 619 |
620 | 620 |
621 void icache_init(); | 621 void icache_init(); |
622 | 622 |
994 } | 994 } |
995 | 995 |
996 void CodeCache::print_summary(outputStream* st, bool detailed) { | 996 void CodeCache::print_summary(outputStream* st, bool detailed) { |
997 size_t total = (_heap->high_boundary() - _heap->low_boundary()); | 997 size_t total = (_heap->high_boundary() - _heap->low_boundary()); |
998 st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT | 998 st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT |
999 "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT | 999 "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT "Kb", |
1000 "Kb max_free_chunk=" SIZE_FORMAT "Kb", | |
1001 total/K, (total - unallocated_capacity())/K, | 1000 total/K, (total - unallocated_capacity())/K, |
1002 maxCodeCacheUsed/K, unallocated_capacity()/K, largest_free_block()/K); | 1001 maxCodeCacheUsed/K, unallocated_capacity()/K); |
1003 | 1002 |
1004 if (detailed) { | 1003 if (detailed) { |
1005 st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", | 1004 st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", |
1006 _heap->low_boundary(), | 1005 _heap->low_boundary(), |
1007 _heap->high(), | 1006 _heap->high(), |
1016 } | 1015 } |
1017 } | 1016 } |
1018 | 1017 |
1019 void CodeCache::log_state(outputStream* st) { | 1018 void CodeCache::log_state(outputStream* st) { |
1020 st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" | 1019 st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" |
1021 " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'" | 1020 " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
1022 " largest_free_block='" SIZE_FORMAT "'", | |
1023 nof_blobs(), nof_nmethods(), nof_adapters(), | 1021 nof_blobs(), nof_nmethods(), nof_adapters(), |
1024 unallocated_capacity(), largest_free_block()); | 1022 unallocated_capacity()); |
1025 } | 1023 } |
1026 | 1024 |
1027 size_t CodeCache::largest_free_block() { | |
1028 // This is called both with and without CodeCache_lock held so | |
1029 // handle both cases. | |
1030 if (CodeCache_lock->owned_by_self()) { | |
1031 return _heap->largest_free_block(); | |
1032 } else { | |
1033 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
1034 return _heap->largest_free_block(); | |
1035 } | |
1036 } |