--- /dev/null	2020-01-14 10:13:11.907818291 +0100
+++ new/src/hotspot/share/gc/shared/objectMarker.cpp	2020-02-21 11:14:40.152195526 +0100
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2020, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "gc/shared/objectMarker.hpp"
+#include "memory/iterator.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/biasedLocking.hpp"
+
+// This implementation uses the existing mark bits in an object for
+// marking. Objects that are marked must later have their headers restored.
+// As most objects are unlocked and don't have their identity hash computed
+// we don't have to save their headers. Instead we save the headers that
+// are "interesting". Later when the headers are restored this implementation
+// restores all headers to their initial value and then restores the few
+// objects that had interesting headers.
+//
+// Future work: This implementation currently uses growable arrays to save
+// the oop and header of interesting objects. As an optimization we could
+// use the same technique as the GC and make use of the unused area
+// between top() and end().
+//
+
+// An ObjectClosure used to restore the mark bits of an object
+class RestoreMarksClosure : public ObjectClosure {
+ public:
+  void do_object(oop o) {
+    if (o != NULL) {
+      markWord mark = o->mark();
+      if (mark.is_marked()) {
+        o->init_mark();
+      }
+    }
+  }
+};
+
+DefaultObjectMarker::DefaultObjectMarker() :
+  _saved_oop_stack(NULL),
+  _saved_mark_stack(NULL) {
+  set_needs_reset(true);
+}
+
+// initialize ObjectMarker - prepares for object marking
+bool DefaultObjectMarker::init() {
+  assert(Thread::current()->is_VM_thread(), "must be VMThread");
+
+  // prepare heap for iteration
+  Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
+
+  // create stacks for interesting headers
+  _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markWord>(4000, true);
+  _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true);
+
+  if (UseBiasedLocking) {
+    BiasedLocking::preserve_marks();
+  }
+
+  return true;
+}
+
+// Object marking is done so restore object headers
+void DefaultObjectMarker::done() {
+  // iterate over all objects and restore the mark bits to
+  // their initial value
+  RestoreMarksClosure blk;
+  if (needs_reset()) {
+    Universe::heap()->object_iterate(&blk);
+  } else {
+    // We don't need to reset mark bits on this call, but reset the
+    // flag to the default for the next call.
+    set_needs_reset(true);
+  }
+
+  // now restore the interesting headers
+  for (int i = 0; i < _saved_oop_stack->length(); i++) {
+    oop o = _saved_oop_stack->at(i);
+    markWord mark = _saved_mark_stack->at(i);
+    o->set_mark(mark);
+  }
+
+  if (UseBiasedLocking) {
+    BiasedLocking::restore_marks();
+  }
+
+  // free the stacks
+  delete _saved_oop_stack;
+  delete _saved_mark_stack;
+
+  delete this;
+}
+
+// mark an object
+bool DefaultObjectMarker::mark(oop o) {
+  assert(Universe::heap()->is_in(o), "sanity check");
+
+  // object's mark word
+  markWord mark = o->mark();
+  if (mark.is_marked()) {
+    return false;
+  }
+
+  if (o->mark_must_be_preserved(mark)) {
+    _saved_mark_stack->push(mark);
+    _saved_oop_stack->push(o);
+  }
+
+  // mark the object
+  o->set_mark(markWord::prototype().set_marked());
+  return true;
+}
+
+// return true if object is marked
+bool DefaultObjectMarker::marked(oop o) {
+  return o->mark().is_marked();
+}