mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
Merge
This commit is contained in:
commit
774e23fae7
9 changed files with 97 additions and 21 deletions
|
@ -598,6 +598,8 @@ StringTable* StringTable::_the_table = NULL;
|
|||
|
||||
bool StringTable::_needs_rehashing = false;
|
||||
|
||||
volatile int StringTable::_parallel_claimed_idx = 0;
|
||||
|
||||
// Pick hashing algorithm
|
||||
unsigned int StringTable::hash_string(const jchar* s, int len) {
|
||||
return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
|
||||
|
@ -761,8 +763,18 @@ void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f)
|
|||
}
|
||||
}
|
||||
|
||||
void StringTable::oops_do(OopClosure* f) {
|
||||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||
void StringTable::buckets_do(OopClosure* f, int start_idx, int end_idx) {
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
assert(0 <= start_idx && start_idx <= limit,
|
||||
err_msg("start_idx (" INT32_FORMAT ") oob?", start_idx));
|
||||
assert(0 <= end_idx && end_idx <= limit,
|
||||
err_msg("end_idx (" INT32_FORMAT ") oob?", end_idx));
|
||||
assert(start_idx <= end_idx,
|
||||
err_msg("Ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
|
||||
start_idx, end_idx));
|
||||
|
||||
for (int i = start_idx; i < end_idx; i += 1) {
|
||||
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
||||
while (entry != NULL) {
|
||||
assert(!entry->is_shared(), "CDS not used for the StringTable");
|
||||
|
@ -774,6 +786,27 @@ void StringTable::oops_do(OopClosure* f) {
|
|||
}
|
||||
}
|
||||
|
||||
void StringTable::oops_do(OopClosure* f) {
|
||||
buckets_do(f, 0, the_table()->table_size());
|
||||
}
|
||||
|
||||
void StringTable::possibly_parallel_oops_do(OopClosure* f) {
|
||||
const int ClaimChunkSize = 32;
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
for (;;) {
|
||||
// Grab next set of buckets to scan
|
||||
int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
|
||||
if (start_idx >= limit) {
|
||||
// End of table
|
||||
break;
|
||||
}
|
||||
|
||||
int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
|
||||
buckets_do(f, start_idx, end_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::verify() {
|
||||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||
HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -246,12 +246,19 @@ private:
|
|||
// Set if one bucket is out of balance due to hash algorithm deficiency
|
||||
static bool _needs_rehashing;
|
||||
|
||||
// Claimed high water mark for parallel chunked scanning
|
||||
static volatile int _parallel_claimed_idx;
|
||||
|
||||
static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
|
||||
oop basic_add(int index, Handle string_or_null, jchar* name, int len,
|
||||
unsigned int hashValue, TRAPS);
|
||||
|
||||
oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
|
||||
|
||||
// Apply the give oop closure to the entries to the buckets
|
||||
// in the range [start_idx, end_idx).
|
||||
static void buckets_do(OopClosure* f, int start_idx, int end_idx);
|
||||
|
||||
StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize,
|
||||
sizeof (HashtableEntry<oop, mtSymbol>)) {}
|
||||
|
||||
|
@ -277,9 +284,12 @@ public:
|
|||
unlink_or_oops_do(cl, NULL);
|
||||
}
|
||||
|
||||
// Invoke "f->do_oop" on the locations of all oops in the table.
|
||||
// Serially invoke "f->do_oop" on the locations of all oops in the table.
|
||||
static void oops_do(OopClosure* f);
|
||||
|
||||
// Possibly parallel version of the above
|
||||
static void possibly_parallel_oops_do(OopClosure* f);
|
||||
|
||||
// Hashing algorithm, used as the hash value used by the
|
||||
// StringTable for bucket selection and comparison (stored in the
|
||||
// HashtableEntry structures). This is used in the String.intern() method.
|
||||
|
@ -315,5 +325,8 @@ public:
|
|||
// Rehash the symbol table if it gets out of balance
|
||||
static void rehash_table();
|
||||
static bool needs_rehashing() { return _needs_rehashing; }
|
||||
|
||||
// Parallel chunked scanning
|
||||
static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
|
||||
};
|
||||
#endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
|
||||
|
|
|
@ -1250,14 +1250,13 @@ uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
|
|||
avg_promoted()->deviation());
|
||||
}
|
||||
|
||||
gclog_or_tty->print( " avg_promoted_padded_avg: %f"
|
||||
gclog_or_tty->print_cr( " avg_promoted_padded_avg: %f"
|
||||
" avg_pretenured_padded_avg: %f"
|
||||
" tenuring_thresh: %d"
|
||||
" target_size: " SIZE_FORMAT,
|
||||
avg_promoted()->padded_average(),
|
||||
_avg_pretenured->padded_average(),
|
||||
tenuring_threshold, target_size);
|
||||
tty->cr();
|
||||
}
|
||||
|
||||
set_survivor_size(target_size);
|
||||
|
@ -1279,7 +1278,7 @@ void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
|
|||
avg_promoted()->sample(promoted + _avg_pretenured->padded_average());
|
||||
|
||||
if (PrintAdaptiveSizePolicy) {
|
||||
gclog_or_tty->print(
|
||||
gclog_or_tty->print_cr(
|
||||
"AdaptiveSizePolicy::update_averages:"
|
||||
" survived: " SIZE_FORMAT
|
||||
" promoted: " SIZE_FORMAT
|
||||
|
|
|
@ -732,13 +732,21 @@ public:
|
|||
// is set so that we always use malloc except for Solaris where we set the
|
||||
// limit to get mapped memory.
|
||||
template <class E, MEMFLAGS F>
|
||||
class ArrayAllocator : StackObj {
|
||||
class ArrayAllocator VALUE_OBJ_CLASS_SPEC {
|
||||
char* _addr;
|
||||
bool _use_malloc;
|
||||
size_t _size;
|
||||
bool _free_in_destructor;
|
||||
public:
|
||||
ArrayAllocator() : _addr(NULL), _use_malloc(false), _size(0) { }
|
||||
~ArrayAllocator() { free(); }
|
||||
ArrayAllocator(bool free_in_destructor = true) :
|
||||
_addr(NULL), _use_malloc(false), _size(0), _free_in_destructor(free_in_destructor) { }
|
||||
|
||||
~ArrayAllocator() {
|
||||
if (_free_in_destructor) {
|
||||
free();
|
||||
}
|
||||
}
|
||||
|
||||
E* allocate(size_t length);
|
||||
void free();
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -47,7 +47,6 @@ enum SH_process_strong_roots_tasks {
|
|||
SH_PS_SystemDictionary_oops_do,
|
||||
SH_PS_ClassLoaderDataGraph_oops_do,
|
||||
SH_PS_jvmti_oops_do,
|
||||
SH_PS_StringTable_oops_do,
|
||||
SH_PS_CodeCache_oops_do,
|
||||
// Leave this one last.
|
||||
SH_PS_NumElements
|
||||
|
@ -127,6 +126,8 @@ SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* outer, bool activate)
|
|||
{
|
||||
if (_active) {
|
||||
outer->change_strong_roots_parity();
|
||||
// Zero the claimed high water mark in the StringTable
|
||||
StringTable::clear_parallel_claimed_index();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,14 +155,16 @@ void SharedHeap::process_strong_roots(bool activate_scope,
|
|||
// Global (strong) JNI handles
|
||||
if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
|
||||
JNIHandles::oops_do(roots);
|
||||
|
||||
// All threads execute this; the individual threads are task groups.
|
||||
CLDToOopClosure roots_from_clds(roots);
|
||||
CLDToOopClosure* roots_from_clds_p = (is_scavenging ? NULL : &roots_from_clds);
|
||||
if (ParallelGCThreads > 0) {
|
||||
Threads::possibly_parallel_oops_do(roots, roots_from_clds_p ,code_roots);
|
||||
if (CollectedHeap::use_parallel_gc_threads()) {
|
||||
Threads::possibly_parallel_oops_do(roots, roots_from_clds_p, code_roots);
|
||||
} else {
|
||||
Threads::oops_do(roots, roots_from_clds_p, code_roots);
|
||||
}
|
||||
|
||||
if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
|
||||
ObjectSynchronizer::oops_do(roots);
|
||||
if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
|
||||
|
@ -189,8 +192,12 @@ void SharedHeap::process_strong_roots(bool activate_scope,
|
|||
}
|
||||
}
|
||||
|
||||
if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
|
||||
if (so & SO_Strings) {
|
||||
// All threads execute the following. A specific chunk of buckets
|
||||
// from the StringTable are the individual tasks.
|
||||
if (so & SO_Strings) {
|
||||
if (CollectedHeap::use_parallel_gc_threads()) {
|
||||
StringTable::possibly_parallel_oops_do(roots);
|
||||
} else {
|
||||
StringTable::oops_do(roots);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1566,6 +1566,15 @@ julong Arguments::limit_by_allocatable_memory(julong limit) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void Arguments::set_heap_base_min_address() {
|
||||
if (FLAG_IS_DEFAULT(HeapBaseMinAddress) && UseG1GC && HeapBaseMinAddress < 1*G) {
|
||||
// By default HeapBaseMinAddress is 2G on all platforms except Solaris x86.
|
||||
// G1 currently needs a lot of C-heap, so on Solaris we have to give G1
|
||||
// some extra space for the C-heap compared to other collectors.
|
||||
FLAG_SET_ERGO(uintx, HeapBaseMinAddress, 1*G);
|
||||
}
|
||||
}
|
||||
|
||||
void Arguments::set_heap_size() {
|
||||
if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) {
|
||||
// Deprecated flag
|
||||
|
@ -3525,6 +3534,8 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
set_heap_base_min_address();
|
||||
|
||||
// Set heap size based on available physical memory
|
||||
set_heap_size();
|
||||
|
||||
|
|
|
@ -315,6 +315,8 @@ class Arguments : AllStatic {
|
|||
// limits the given memory size by the maximum amount of memory this process is
|
||||
// currently allowed to allocate or reserve.
|
||||
static julong limit_by_allocatable_memory(julong size);
|
||||
// Setup HeapBaseMinAddress
|
||||
static void set_heap_base_min_address();
|
||||
// Setup heap size
|
||||
static void set_heap_size();
|
||||
// Based on automatic selection criteria, should the
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
|
||||
BitMap::BitMap(bm_word_t* map, idx_t size_in_bits) :
|
||||
_map(map), _size(size_in_bits)
|
||||
_map(map), _size(size_in_bits), _map_allocator(false)
|
||||
{
|
||||
assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
|
||||
assert(size_in_bits >= 0, "just checking");
|
||||
|
@ -49,7 +49,7 @@ BitMap::BitMap(bm_word_t* map, idx_t size_in_bits) :
|
|||
|
||||
|
||||
BitMap::BitMap(idx_t size_in_bits, bool in_resource_area) :
|
||||
_map(NULL), _size(0)
|
||||
_map(NULL), _size(0), _map_allocator(false)
|
||||
{
|
||||
assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
|
||||
resize(size_in_bits, in_resource_area);
|
||||
|
@ -65,8 +65,10 @@ void BitMap::resize(idx_t size_in_bits, bool in_resource_area) {
|
|||
if (in_resource_area) {
|
||||
_map = NEW_RESOURCE_ARRAY(bm_word_t, new_size_in_words);
|
||||
} else {
|
||||
if (old_map != NULL) FREE_C_HEAP_ARRAY(bm_word_t, _map, mtInternal);
|
||||
_map = NEW_C_HEAP_ARRAY(bm_word_t, new_size_in_words, mtInternal);
|
||||
if (old_map != NULL) {
|
||||
_map_allocator.free();
|
||||
}
|
||||
_map = _map_allocator.allocate(new_size_in_words);
|
||||
}
|
||||
Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) _map,
|
||||
MIN2(old_size_in_words, new_size_in_words));
|
||||
|
|
|
@ -48,6 +48,7 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
|
|||
} RangeSizeHint;
|
||||
|
||||
private:
|
||||
ArrayAllocator<bm_word_t, mtInternal> _map_allocator;
|
||||
bm_word_t* _map; // First word in bitmap
|
||||
idx_t _size; // Size of bitmap (in bits)
|
||||
|
||||
|
@ -113,7 +114,7 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
|
|||
public:
|
||||
|
||||
// Constructs a bitmap with no map, and size 0.
|
||||
BitMap() : _map(NULL), _size(0) {}
|
||||
BitMap() : _map(NULL), _size(0), _map_allocator(false) {}
|
||||
|
||||
// Constructs a bitmap with the given map and size.
|
||||
BitMap(bm_word_t* map, idx_t size_in_bits);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue