< prev index next >

src/share/vm/jfr/leakprofiler/chains/dfsClosure.cpp

Print this page
rev 9055 : 8214542: JFR: Old Object Sample event slow on a deep heap in debug builds
Reviewed-by: egahlin, rwestberg
rev 9057 : 8229437: assert(is_aligned(ref, HeapWordSize)) failed: invariant
Reviewed-by: egahlin

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -21,18 +21,18 @@
  * questions.
  *
  */
 
 #include "precompiled.hpp"
+#include "jfr/leakprofiler/chains/bitset.hpp"
 #include "jfr/leakprofiler/chains/dfsClosure.hpp"
 #include "jfr/leakprofiler/chains/edge.hpp"
 #include "jfr/leakprofiler/chains/edgeStore.hpp"
+#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
 #include "jfr/leakprofiler/utilities/granularTimer.hpp"
-#include "jfr/leakprofiler/chains/bitset.hpp"
-#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
 #include "jfr/leakprofiler/utilities/rootType.hpp"
-#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
+#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/align.hpp"
 

@@ -85,19 +85,19 @@
   _start_edge = NULL;
 
   // Mark root set, to avoid going sideways
   _max_depth = 1;
   _ignore_root_set = false;
-  DFSClosure dfs1;
-  RootSetClosure::process_roots(&dfs1);
+  DFSClosure dfs;
+  RootSetClosure<DFSClosure> rs(&dfs);
+  rs.process();
 
   // Depth-first search
   _max_depth = max_dfs_depth;
   _ignore_root_set = true;
   assert(_start_edge == NULL, "invariant");
-  DFSClosure dfs2;
-  RootSetClosure::process_roots(&dfs2);
+  rs.process();
 }
 
 void DFSClosure::closure_impl(const oop* reference, const oop pointee) {
   assert(pointee != NULL, "invariant");
   assert(reference != NULL, "invariant");

@@ -130,34 +130,33 @@
     pointee->oop_iterate(&next_level);
   }
 }
 
 void DFSClosure::add_chain() {
-  const size_t length = _start_edge == NULL ? _depth + 1 :
-                        _start_edge->distance_to_root() + 1 + _depth + 1;
+  const size_t array_length = _depth + 2;
 
   ResourceMark rm;
-  Edge* const chain = NEW_RESOURCE_ARRAY(Edge, length);
+  Edge* const chain = NEW_RESOURCE_ARRAY(Edge, array_length);
   size_t idx = 0;
 
   // aggregate from depth-first search
   const DFSClosure* c = this;
   while (c != NULL) {
-    chain[idx++] = Edge(NULL, c->reference());
+    const size_t next = idx + 1;
+    chain[idx++] = Edge(&chain[next], c->reference());
     c = c->parent();
   }
-
-  assert(idx == _depth + 1, "invariant");
+  assert(_depth + 1 == idx, "invariant");
+  assert(array_length == idx + 1, "invariant");
 
   // aggregate from breadth-first search
-  const Edge* current = _start_edge;
-  while (current != NULL) {
-    chain[idx++] = Edge(NULL, current->reference());
-    current = current->parent();
+  if (_start_edge != NULL) {
+    chain[idx++] = *_start_edge;
+  } else {
+    chain[idx - 1] = Edge(NULL, chain[idx - 1].reference());
   }
-  assert(idx == length, "invariant");
-  _edge_store->add_chain(chain, length);
+  _edge_store->put_chain(chain, idx + (_start_edge != NULL ? _start_edge->distance_to_root() : 0));
 }
 
 void DFSClosure::do_oop(oop* ref) {
   assert(ref != NULL, "invariant");
   assert(is_aligned(ref, HeapWordSize), "invariant");

@@ -173,5 +172,12 @@
   const oop pointee = oopDesc::load_decode_heap_oop(ref);
   if (pointee != NULL) {
     closure_impl(UnifiedOop::encode(ref), pointee);
   }
 }
+
+void DFSClosure::do_root(const oop* ref) {
+  assert(ref != NULL, "invariant");
+  const oop pointee = UnifiedOop::dereference(ref);
+  assert(pointee != NULL, "invariant");
+  closure_impl(ref, pointee);
+}
< prev index next >