changeset 8518:aad15df39b88

Merge
author asaha
date Mon, 26 Jun 2017 22:29:37 -0700
parents 40aca961645d b47c7d21e788
children 8c937a2e846e 6470230caf2a
files .hgtags
diffstat 3 files changed, 73 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Jun 26 22:21:49 2017 -0700
+++ b/.hgtags	Mon Jun 26 22:29:37 2017 -0700
@@ -967,6 +967,8 @@
 829ea9b92cda9545652f1b309f56c57383024ebb jdk8u131-b11
 41e0713bcca27cef5d6a9afd44c7ca4811937713 jdk8u131-b31
 e318654a4fa352a06935dd56eebf88ae387b31f9 jdk8u131-b32
+32998fc932dc58c6bbac185cc17d2752fa6dba4c jdk8u131-b33
+50b3fa6791f46bc582528bdc7f6311b3b6832c51 jdk8u131-b34
 692bc6b674dcab72453de08ee9da0856a7e41c0f jdk8u141-b00
 0cee0db0180b64655751e7058c251103f9660f85 jdk8u141-b01
 82435799636c8b50a090aebcb5af49946afa7bb5 jdk8u141-b02
--- a/src/share/vm/classfile/classLoaderData.cpp	Mon Jun 26 22:21:49 2017 -0700
+++ b/src/share/vm/classfile/classLoaderData.cpp	Mon Jun 26 22:29:37 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -78,7 +78,7 @@
   // The null-class-loader should always be kept alive.
   _keep_alive(is_anonymous || h_class_loader.is_null()),
   _metaspace(NULL), _unloading(false), _klasses(NULL),
-  _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
+  _claimed(0), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL),
   _next(NULL), _dependencies(dependencies),
   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {
     // empty
@@ -96,6 +96,45 @@
   _list_head = oopFactory::new_objectArray(2, CHECK);
 }
 
+ClassLoaderData::ChunkedHandleList::~ChunkedHandleList() {
+  Chunk* c = _head;
+  while (c != NULL) {
+    Chunk* next = c->_next;
+    delete c;
+    c = next;
+  }
+}
+
+oop* ClassLoaderData::ChunkedHandleList::add(oop o) {
+  if (_head == NULL || _head->_size == Chunk::CAPACITY) {
+    Chunk* next = new Chunk(_head);
+    OrderAccess::release_store_ptr(&_head, next);
+  }
+  oop* handle = &_head->_data[_head->_size];
+  *handle = o;
+  OrderAccess::release_store(&_head->_size, _head->_size + 1);
+  return handle;
+}
+
+inline void ClassLoaderData::ChunkedHandleList::oops_do_chunk(OopClosure* f, Chunk* c, const juint size) {
+  for (juint i = 0; i < size; i++) {
+    if (c->_data[i] != NULL) {
+      f->do_oop(&c->_data[i]);
+    }
+  }
+}
+
+void ClassLoaderData::ChunkedHandleList::oops_do(OopClosure* f) {
+  Chunk* head = (Chunk*) OrderAccess::load_ptr_acquire(&_head);
+  if (head != NULL) {
+    // Must be careful when reading size of head
+    oops_do_chunk(f, head, OrderAccess::load_acquire(&head->_size));
+    for (Chunk* c = head->_next; c != NULL; c = c->_next) {
+      oops_do_chunk(f, c, c->_size);
+    }
+  }
+}
+
 bool ClassLoaderData::claim() {
   if (_claimed == 1) {
     return false;
@@ -111,7 +150,7 @@
 
   f->do_oop(&_class_loader);
   _dependencies.oops_do(f);
-  _handles->oops_do(f);
+  _handles.oops_do(f);
   if (klass_closure != NULL) {
     classes_do(klass_closure);
   }
@@ -342,11 +381,6 @@
     _metaspace = NULL;
     // release the metaspace
     delete m;
-    // release the handles
-    if (_handles != NULL) {
-      JNIHandleBlock::release_block(_handles);
-      _handles = NULL;
-    }
   }
 
   // Clear all the JNI handles for methods
@@ -406,15 +440,9 @@
   return _metaspace;
 }
 
-JNIHandleBlock* ClassLoaderData::handles() const           { return _handles; }
-void ClassLoaderData::set_handles(JNIHandleBlock* handles) { _handles = handles; }
-
 jobject ClassLoaderData::add_handle(Handle h) {
   MutexLockerEx ml(metaspace_lock(),  Mutex::_no_safepoint_check_flag);
-  if (handles() == NULL) {
-    set_handles(JNIHandleBlock::allocate_block());
-  }
-  return handles()->allocate_handle(h());
+  return (jobject) _handles.add(h());
 }
 
 // Add this metadata pointer to be freed when it's safe.  This is only during
@@ -479,7 +507,6 @@
       p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name());
   if (claimed()) out->print(" claimed ");
   if (is_unloading()) out->print(" unloading ");
-  out->print(" handles " INTPTR_FORMAT, p2i(handles()));
   out->cr();
   if (metaspace_or_null() != NULL) {
     out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
--- a/src/share/vm/classfile/classLoaderData.hpp	Mon Jun 26 22:21:49 2017 -0700
+++ b/src/share/vm/classfile/classLoaderData.hpp	Mon Jun 26 22:29:37 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -51,7 +51,6 @@
 
 class ClassLoaderData;
 class JNIMethodBlock;
-class JNIHandleBlock;
 class Metadebug;
 
 // GC root for walking class loader data created
@@ -145,6 +144,31 @@
     void oops_do(OopClosure* f);
   };
 
+  class ChunkedHandleList VALUE_OBJ_CLASS_SPEC {
+    struct Chunk : public CHeapObj<mtClass> {
+      static const size_t CAPACITY = 32;
+
+      oop _data[CAPACITY];
+      volatile juint _size;
+      Chunk* _next;
+
+      Chunk(Chunk* c) : _next(c), _size(0) { }
+    };
+
+    Chunk* _head;
+
+    void oops_do_chunk(OopClosure* f, Chunk* c, const juint size);
+
+   public:
+    ChunkedHandleList() : _head(NULL) {}
+    ~ChunkedHandleList();
+
+    // Only one thread at a time can add, guarded by ClassLoaderData::metaspace_lock().
+    // However, multiple threads can execute oops_do concurrently with add.
+    oop* add(oop o);
+    void oops_do(OopClosure* f);
+  };
+
   friend class ClassLoaderDataGraph;
   friend class ClassLoaderDataGraphKlassIteratorAtomic;
   friend class ClassLoaderDataGraphMetaspaceIterator;
@@ -169,7 +193,8 @@
                            // Has to be an int because we cas it.
   Klass* _klasses;         // The classes defined by the class loader.
 
-  JNIHandleBlock* _handles; // Handles to constant pool arrays
+  ChunkedHandleList _handles; // Handles to constant pool arrays, etc, which
+                              // have the same life cycle of the corresponding ClassLoader.
 
   // These method IDs are created for the class loader and set to NULL when the
   // class loader is unloaded.  They are rarely freed, only for redefine classes
@@ -196,9 +221,6 @@
 
   void set_metaspace(Metaspace* m) { _metaspace = m; }
 
-  JNIHandleBlock* handles() const;
-  void set_handles(JNIHandleBlock* handles);
-
   Mutex* metaspace_lock() const { return _metaspace_lock; }
 
   // GC interface.