United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6770949 minor tweaks before 6655638
JDK-6770949 : minor tweaks before 6655638

Details
Type:
Bug
Submit Date:
2008-11-13
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
generic
Sub-Component:
compiler
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
hs14 (b08)

Related Reports
Backport:
Backport:

Sub Tasks

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
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;
 }
                                     
2008-11-13
EVALUATION

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



Hardware and Software, Engineered to Work Together