Thu, 20 Jun 2013 10:03:58 +0200
Merge
src/share/vm/memory/allocation.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/classfile/symbolTable.cpp Wed Jun 19 18:13:52 2013 +0200 1.2 +++ b/src/share/vm/classfile/symbolTable.cpp Thu Jun 20 10:03:58 2013 +0200 1.3 @@ -598,6 +598,8 @@ 1.4 1.5 bool StringTable::_needs_rehashing = false; 1.6 1.7 +volatile int StringTable::_parallel_claimed_idx = 0; 1.8 + 1.9 // Pick hashing algorithm 1.10 unsigned int StringTable::hash_string(const jchar* s, int len) { 1.11 return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : 1.12 @@ -761,8 +763,18 @@ 1.13 } 1.14 } 1.15 1.16 -void StringTable::oops_do(OopClosure* f) { 1.17 - for (int i = 0; i < the_table()->table_size(); ++i) { 1.18 +void StringTable::buckets_do(OopClosure* f, int start_idx, int end_idx) { 1.19 + const int limit = the_table()->table_size(); 1.20 + 1.21 + assert(0 <= start_idx && start_idx <= limit, 1.22 + err_msg("start_idx (" INT32_FORMAT ") oob?", start_idx)); 1.23 + assert(0 <= end_idx && end_idx <= limit, 1.24 + err_msg("end_idx (" INT32_FORMAT ") oob?", end_idx)); 1.25 + assert(start_idx <= end_idx, 1.26 + err_msg("Ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT, 1.27 + start_idx, end_idx)); 1.28 + 1.29 + for (int i = start_idx; i < end_idx; i += 1) { 1.30 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); 1.31 while (entry != NULL) { 1.32 assert(!entry->is_shared(), "CDS not used for the StringTable"); 1.33 @@ -774,6 +786,27 @@ 1.34 } 1.35 } 1.36 1.37 +void StringTable::oops_do(OopClosure* f) { 1.38 + buckets_do(f, 0, the_table()->table_size()); 1.39 +} 1.40 + 1.41 +void StringTable::possibly_parallel_oops_do(OopClosure* f) { 1.42 + const int ClaimChunkSize = 32; 1.43 + const int limit = the_table()->table_size(); 1.44 + 1.45 + for (;;) { 1.46 + // Grab next set of buckets to scan 1.47 + int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; 1.48 + if (start_idx >= limit) { 1.49 + // End of table 1.50 + break; 1.51 + } 1.52 + 1.53 + int end_idx = MIN2(limit, start_idx + ClaimChunkSize); 1.54 + buckets_do(f, start_idx, end_idx); 1.55 + } 1.56 +} 1.57 + 1.58 void StringTable::verify() { 1.59 for (int i = 0; i < the_table()->table_size(); ++i) { 1.60 HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
2.1 --- a/src/share/vm/classfile/symbolTable.hpp Wed Jun 19 18:13:52 2013 +0200 2.2 +++ b/src/share/vm/classfile/symbolTable.hpp Thu Jun 20 10:03:58 2013 +0200 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -246,12 +246,19 @@ 2.11 // Set if one bucket is out of balance due to hash algorithm deficiency 2.12 static bool _needs_rehashing; 2.13 2.14 + // Claimed high water mark for parallel chunked scanning 2.15 + static volatile int _parallel_claimed_idx; 2.16 + 2.17 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); 2.18 oop basic_add(int index, Handle string_or_null, jchar* name, int len, 2.19 unsigned int hashValue, TRAPS); 2.20 2.21 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); 2.22 2.23 + // Apply the give oop closure to the entries to the buckets 2.24 + // in the range [start_idx, end_idx). 2.25 + static void buckets_do(OopClosure* f, int start_idx, int end_idx); 2.26 + 2.27 StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize, 2.28 sizeof (HashtableEntry<oop, mtSymbol>)) {} 2.29 2.30 @@ -277,9 +284,12 @@ 2.31 unlink_or_oops_do(cl, NULL); 2.32 } 2.33 2.34 - // Invoke "f->do_oop" on the locations of all oops in the table. 2.35 + // Serially invoke "f->do_oop" on the locations of all oops in the table. 2.36 static void oops_do(OopClosure* f); 2.37 2.38 + // Possibly parallel version of the above 2.39 + static void possibly_parallel_oops_do(OopClosure* f); 2.40 + 2.41 // Hashing algorithm, used as the hash value used by the 2.42 // StringTable for bucket selection and comparison (stored in the 2.43 // HashtableEntry structures). This is used in the String.intern() method. 2.44 @@ -315,5 +325,8 @@ 2.45 // Rehash the symbol table if it gets out of balance 2.46 static void rehash_table(); 2.47 static bool needs_rehashing() { return _needs_rehashing; } 2.48 + 2.49 + // Parallel chunked scanning 2.50 + static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } 2.51 }; 2.52 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
3.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp Wed Jun 19 18:13:52 2013 +0200 3.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp Thu Jun 20 10:03:58 2013 +0200 3.3 @@ -1250,14 +1250,13 @@ 3.4 avg_promoted()->deviation()); 3.5 } 3.6 3.7 - gclog_or_tty->print( " avg_promoted_padded_avg: %f" 3.8 + gclog_or_tty->print_cr( " avg_promoted_padded_avg: %f" 3.9 " avg_pretenured_padded_avg: %f" 3.10 " tenuring_thresh: %d" 3.11 " target_size: " SIZE_FORMAT, 3.12 avg_promoted()->padded_average(), 3.13 _avg_pretenured->padded_average(), 3.14 tenuring_threshold, target_size); 3.15 - tty->cr(); 3.16 } 3.17 3.18 set_survivor_size(target_size); 3.19 @@ -1279,7 +1278,7 @@ 3.20 avg_promoted()->sample(promoted + _avg_pretenured->padded_average()); 3.21 3.22 if (PrintAdaptiveSizePolicy) { 3.23 - gclog_or_tty->print( 3.24 + gclog_or_tty->print_cr( 3.25 "AdaptiveSizePolicy::update_averages:" 3.26 " survived: " SIZE_FORMAT 3.27 " promoted: " SIZE_FORMAT
4.1 --- a/src/share/vm/memory/allocation.hpp Wed Jun 19 18:13:52 2013 +0200 4.2 +++ b/src/share/vm/memory/allocation.hpp Thu Jun 20 10:03:58 2013 +0200 4.3 @@ -732,13 +732,21 @@ 4.4 // is set so that we always use malloc except for Solaris where we set the 4.5 // limit to get mapped memory. 4.6 template <class E, MEMFLAGS F> 4.7 -class ArrayAllocator : StackObj { 4.8 +class ArrayAllocator VALUE_OBJ_CLASS_SPEC { 4.9 char* _addr; 4.10 bool _use_malloc; 4.11 size_t _size; 4.12 + bool _free_in_destructor; 4.13 public: 4.14 - ArrayAllocator() : _addr(NULL), _use_malloc(false), _size(0) { } 4.15 - ~ArrayAllocator() { free(); } 4.16 + ArrayAllocator(bool free_in_destructor = true) : 4.17 + _addr(NULL), _use_malloc(false), _size(0), _free_in_destructor(free_in_destructor) { } 4.18 + 4.19 + ~ArrayAllocator() { 4.20 + if (_free_in_destructor) { 4.21 + free(); 4.22 + } 4.23 + } 4.24 + 4.25 E* allocate(size_t length); 4.26 void free(); 4.27 };
5.1 --- a/src/share/vm/memory/sharedHeap.cpp Wed Jun 19 18:13:52 2013 +0200 5.2 +++ b/src/share/vm/memory/sharedHeap.cpp Thu Jun 20 10:03:58 2013 +0200 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -47,7 +47,6 @@ 5.11 SH_PS_SystemDictionary_oops_do, 5.12 SH_PS_ClassLoaderDataGraph_oops_do, 5.13 SH_PS_jvmti_oops_do, 5.14 - SH_PS_StringTable_oops_do, 5.15 SH_PS_CodeCache_oops_do, 5.16 // Leave this one last. 5.17 SH_PS_NumElements 5.18 @@ -127,6 +126,8 @@ 5.19 { 5.20 if (_active) { 5.21 outer->change_strong_roots_parity(); 5.22 + // Zero the claimed high water mark in the StringTable 5.23 + StringTable::clear_parallel_claimed_index(); 5.24 } 5.25 } 5.26 5.27 @@ -154,14 +155,16 @@ 5.28 // Global (strong) JNI handles 5.29 if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do)) 5.30 JNIHandles::oops_do(roots); 5.31 + 5.32 // All threads execute this; the individual threads are task groups. 5.33 CLDToOopClosure roots_from_clds(roots); 5.34 CLDToOopClosure* roots_from_clds_p = (is_scavenging ? NULL : &roots_from_clds); 5.35 - if (ParallelGCThreads > 0) { 5.36 - Threads::possibly_parallel_oops_do(roots, roots_from_clds_p ,code_roots); 5.37 + if (CollectedHeap::use_parallel_gc_threads()) { 5.38 + Threads::possibly_parallel_oops_do(roots, roots_from_clds_p, code_roots); 5.39 } else { 5.40 Threads::oops_do(roots, roots_from_clds_p, code_roots); 5.41 } 5.42 + 5.43 if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do)) 5.44 ObjectSynchronizer::oops_do(roots); 5.45 if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do)) 5.46 @@ -189,8 +192,12 @@ 5.47 } 5.48 } 5.49 5.50 - if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) { 5.51 - if (so & SO_Strings) { 5.52 + // All threads execute the following. A specific chunk of buckets 5.53 + // from the StringTable are the individual tasks. 5.54 + if (so & SO_Strings) { 5.55 + if (CollectedHeap::use_parallel_gc_threads()) { 5.56 + StringTable::possibly_parallel_oops_do(roots); 5.57 + } else { 5.58 StringTable::oops_do(roots); 5.59 } 5.60 }
6.1 --- a/src/share/vm/runtime/arguments.cpp Wed Jun 19 18:13:52 2013 +0200 6.2 +++ b/src/share/vm/runtime/arguments.cpp Thu Jun 20 10:03:58 2013 +0200 6.3 @@ -1566,6 +1566,15 @@ 6.4 return result; 6.5 } 6.6 6.7 +void Arguments::set_heap_base_min_address() { 6.8 + if (FLAG_IS_DEFAULT(HeapBaseMinAddress) && UseG1GC && HeapBaseMinAddress < 1*G) { 6.9 + // By default HeapBaseMinAddress is 2G on all platforms except Solaris x86. 6.10 + // G1 currently needs a lot of C-heap, so on Solaris we have to give G1 6.11 + // some extra space for the C-heap compared to other collectors. 6.12 + FLAG_SET_ERGO(uintx, HeapBaseMinAddress, 1*G); 6.13 + } 6.14 +} 6.15 + 6.16 void Arguments::set_heap_size() { 6.17 if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) { 6.18 // Deprecated flag 6.19 @@ -3525,6 +3534,8 @@ 6.20 } 6.21 } 6.22 6.23 + set_heap_base_min_address(); 6.24 + 6.25 // Set heap size based on available physical memory 6.26 set_heap_size(); 6.27
7.1 --- a/src/share/vm/runtime/arguments.hpp Wed Jun 19 18:13:52 2013 +0200 7.2 +++ b/src/share/vm/runtime/arguments.hpp Thu Jun 20 10:03:58 2013 +0200 7.3 @@ -315,6 +315,8 @@ 7.4 // limits the given memory size by the maximum amount of memory this process is 7.5 // currently allowed to allocate or reserve. 7.6 static julong limit_by_allocatable_memory(julong size); 7.7 + // Setup HeapBaseMinAddress 7.8 + static void set_heap_base_min_address(); 7.9 // Setup heap size 7.10 static void set_heap_size(); 7.11 // Based on automatic selection criteria, should the
8.1 --- a/src/share/vm/utilities/bitMap.cpp Wed Jun 19 18:13:52 2013 +0200 8.2 +++ b/src/share/vm/utilities/bitMap.cpp Thu Jun 20 10:03:58 2013 +0200 8.3 @@ -41,7 +41,7 @@ 8.4 8.5 8.6 BitMap::BitMap(bm_word_t* map, idx_t size_in_bits) : 8.7 - _map(map), _size(size_in_bits) 8.8 + _map(map), _size(size_in_bits), _map_allocator(false) 8.9 { 8.10 assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption."); 8.11 assert(size_in_bits >= 0, "just checking"); 8.12 @@ -49,7 +49,7 @@ 8.13 8.14 8.15 BitMap::BitMap(idx_t size_in_bits, bool in_resource_area) : 8.16 - _map(NULL), _size(0) 8.17 + _map(NULL), _size(0), _map_allocator(false) 8.18 { 8.19 assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption."); 8.20 resize(size_in_bits, in_resource_area); 8.21 @@ -65,8 +65,10 @@ 8.22 if (in_resource_area) { 8.23 _map = NEW_RESOURCE_ARRAY(bm_word_t, new_size_in_words); 8.24 } else { 8.25 - if (old_map != NULL) FREE_C_HEAP_ARRAY(bm_word_t, _map, mtInternal); 8.26 - _map = NEW_C_HEAP_ARRAY(bm_word_t, new_size_in_words, mtInternal); 8.27 + if (old_map != NULL) { 8.28 + _map_allocator.free(); 8.29 + } 8.30 + _map = _map_allocator.allocate(new_size_in_words); 8.31 } 8.32 Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) _map, 8.33 MIN2(old_size_in_words, new_size_in_words));
9.1 --- a/src/share/vm/utilities/bitMap.hpp Wed Jun 19 18:13:52 2013 +0200 9.2 +++ b/src/share/vm/utilities/bitMap.hpp Thu Jun 20 10:03:58 2013 +0200 9.3 @@ -48,6 +48,7 @@ 9.4 } RangeSizeHint; 9.5 9.6 private: 9.7 + ArrayAllocator<bm_word_t, mtInternal> _map_allocator; 9.8 bm_word_t* _map; // First word in bitmap 9.9 idx_t _size; // Size of bitmap (in bits) 9.10 9.11 @@ -113,7 +114,7 @@ 9.12 public: 9.13 9.14 // Constructs a bitmap with no map, and size 0. 9.15 - BitMap() : _map(NULL), _size(0) {} 9.16 + BitMap() : _map(NULL), _size(0), _map_allocator(false) {} 9.17 9.18 // Constructs a bitmap with the given map and size. 9.19 BitMap(bm_word_t* map, idx_t size_in_bits);