JDK-6770949 : minor tweaks before 6655638
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2008-11-13
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u14Fixed 7Fixed hs14Fixed
Description
Some small changes from the proposed fix to 6655638 (meth.patch of openjdk/mlvm) need to go in as a first push, because (a) they are not integral to method handles, and (b) they cannot be conditionalized under MethodHandles.

The change to hashtable.cpp make it scale better when the load is very high.

Changes to debug.cpp are bug fixes.

Changes to array classes make them easier to optimize.

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/275a3b7ff0d6
13-11-2008

SUGGESTED FIX diff --git a/src/share/vm/utilities/array.hpp b/src/share/vm/utilities/array.hpp --- a/src/share/vm/utilities/array.hpp +++ b/src/share/vm/utilities/array.hpp @@ -40,11 +40,18 @@ class ResourceArray: public ResourceObj _length = 0; _data = NULL; DEBUG_ONLY(init_nesting();) + // client may call initialize, at most once } ResourceArray(size_t esize, int length) { + DEBUG_ONLY(_data = NULL); + initialize(esize, length); + } + + void initialize(size_t esize, int length) { assert(length >= 0, "illegal length"); + assert(_data == NULL, "must be new object"); _length = length; _data = resource_allocate_bytes(esize * length); DEBUG_ONLY(init_nesting();) @@ -111,7 +118,10 @@ class CHeapArray: public CHeapObj { /* creation */ \ array_name() : base_class() {} \ array_name(const int length) : base_class(esize, length) {} \ - array_name(const int length, const etype fx) : base_class(esize, length) { \ + array_name(const int length, const etype fx) { initialize(length, fx); } \ + void initialize(const int length) { base_class::initialize(esize, length); } \ + void initialize(const int length, const etype fx) { \ + initialize(length); \ for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \ } \ \ @@ -157,16 +167,29 @@ class CHeapArray: public CHeapObj { \ public: \ /* creation */ \ - stack_name() : array_name() { _size = 0; } \ - stack_name(const int size) : array_name(size){ _length = 0; _size = size; } \ - stack_name(const int size, const etype fx) : array_name(size, fx) { _size = size; } \ + stack_name() : array_name() { _size = 0; } \ + stack_name(const int size) { initialize(size); } \ + stack_name(const int size, const etype fx) { initialize(size, fx); } \ + void initialize(const int size, const etype fx) { \ + _size = size; \ + array_name::initialize(size, fx); \ + /* _length == size, allocation and size are the same */ \ + } \ + void initialize(const int size) { \ + _size = size; \ + array_name::initialize(size); \ + _length = 0; /* reset length to zero; _size records the allocation */ \ + } \ \ /* standard operations */ \ int size() const { return _size; } \ \ - void push(const etype x) { \ - if (length() >= size()) expand(esize, length(), _size); \ - ((etype*)_data)[_length++] = x; \ + int push(const etype x) { \ + int len = length(); \ + if (len >= size()) expand(esize, len, _size); \ + ((etype*)_data)[len] = x; \ + _length = len+1; \ + return len; \ } \ \ etype pop() { \ @@ -235,7 +258,7 @@ class CHeapArray: public CHeapObj { int capacity() const { return size(); } \ void clear() { truncate(0); } \ void trunc_to(const int length) { truncate(length); } \ - void append(const etype x) { push(x); } \ + int append(const etype x) { return push(x); } \ void appendAll(const stack_name* stack) { push_all(stack); } \ etype last() const { return top(); } \ }; \ diff --git a/src/share/vm/utilities/debug.cpp b/src/share/vm/utilities/debug.cpp --- a/src/share/vm/utilities/debug.cpp +++ b/src/share/vm/utilities/debug.cpp @@ -567,7 +567,7 @@ static void find(intptr_t x, bool print_ } // the InlineCacheBuffer is using stubs generated into a buffer blob if (InlineCacheBuffer::contains(addr)) { - tty->print_cr(INTPTR_FORMAT "is pointing into InlineCacheBuffer", addr); + tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr); return; } VtableStub* v = VtableStubs::stub_containing(addr); @@ -595,7 +595,7 @@ static void find(intptr_t x, bool print_ return; } - if (Universe::heap()->is_in_reserved(addr)) { + if (Universe::heap()->is_in(addr)) { HeapWord* p = Universe::heap()->block_start(addr); bool print = false; // If we couldn't find it it just may mean that heap wasn't parseable @@ -621,24 +621,28 @@ static void find(intptr_t x, bool print_ } return; } + } else if (Universe::heap()->is_in_reserved(addr)) { + tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr); + return; } + if (JNIHandles::is_global_handle((jobject) addr)) { - tty->print_cr(INTPTR_FORMAT "is a global jni handle", addr); + tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr); return; } if (JNIHandles::is_weak_global_handle((jobject) addr)) { - tty->print_cr(INTPTR_FORMAT "is a weak global jni handle", addr); + tty->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr); return; } if (JNIHandleBlock::any_contains((jobject) addr)) { - tty->print_cr(INTPTR_FORMAT "is a local jni handle", addr); + tty->print_cr(INTPTR_FORMAT " is a local jni handle", addr); return; } for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { - // Check for priviledge stack + // Check for privilege stack if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) { - tty->print_cr(INTPTR_FORMAT "is pointing into the priviledge stack for thread: " INTPTR_FORMAT, addr, thread); + tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread); return; } // If the addr is a java thread print information about that. @@ -659,7 +663,7 @@ static void find(intptr_t x, bool print_ return; } - tty->print_cr(INTPTR_FORMAT "is pointing to unknown location", addr); + tty->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr); } diff --git a/src/share/vm/utilities/growableArray.hpp b/src/share/vm/utilities/growableArray.hpp --- a/src/share/vm/utilities/growableArray.hpp +++ b/src/share/vm/utilities/growableArray.hpp @@ -111,6 +111,12 @@ class GenericGrowableArray : public Reso } void* raw_allocate(int elementSize); + + // some uses pass the Thread explicitly for speed (4990299 tuning) + void* raw_allocate(Thread* thread, int elementSize) { + assert(on_stack(), "fast ResourceObj path only"); + return (void*)resource_allocate_bytes(thread, elementSize * _max); + } }; template<class E> class GrowableArray : public GenericGrowableArray { @@ -121,6 +127,11 @@ template<class E> class GrowableArray : void raw_at_put_grow(int i, const E& p, const E& fill); void clear_and_deallocate(); public: + GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) { + _data = (E*)raw_allocate(thread, sizeof(E)); + for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); + } + GrowableArray(int initial_size, bool C_heap = false) : GenericGrowableArray(initial_size, 0, C_heap) { _data = (E*)raw_allocate(sizeof(E)); for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); @@ -159,10 +170,12 @@ template<class E> class GrowableArray : void print(); - void append(const E& elem) { + int append(const E& elem) { check_nesting(); if (_len == _max) grow(_len); - _data[_len++] = elem; + int idx = _len++; + _data[idx] = elem; + return idx; } void append_if_missing(const E& elem) { diff --git a/src/share/vm/utilities/hashtable.cpp b/src/share/vm/utilities/hashtable.cpp --- a/src/share/vm/utilities/hashtable.cpp +++ b/src/share/vm/utilities/hashtable.cpp @@ -43,9 +43,11 @@ BasicHashtableEntry* BasicHashtable::new entry = _free_list; _free_list = _free_list->next(); } else { - const int block_size = 500; - if (_first_free_entry == _end_block) { + if (_first_free_entry + _entry_size >= _end_block) { + int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries)); int len = _entry_size * block_size; + len = 1 << log2_intptr(len); // round down to power of 2 + assert(len >= _entry_size, ""); _first_free_entry = NEW_C_HEAP_ARRAY(char, len); _end_block = _first_free_entry + len; } @@ -53,6 +55,7 @@ BasicHashtableEntry* BasicHashtable::new _first_free_entry += _entry_size; } + assert(_entry_size % HeapWordSize == 0, ""); entry->set_hash(hashValue); return entry; }
13-11-2008