Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8244997: Convert the JavaThread::_threadObj oop to use OopStorage
Move the oop and handle releasing it in the service thread.  Remove Universe::oops_do from callers.

Co-authored-by: Erik Osterlund <erik.osterlund@oracle.com>
Co-authored-by: Tom Rodriguez <tom.rodriguez@oracle.com>
Reviewed-by: dholmes, zgu, eosterlund, cjplummer
  • Loading branch information
3 people committed Aug 7, 2020
1 parent b6d88a9 commit 21b99411de49bf40ce025ba93e6b87bb0fcd4e0b
Show file tree
Hide file tree
Showing 46 changed files with 162 additions and 207 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 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
@@ -48,7 +48,7 @@ LIR_Opr LIR_OprFact::double_fpu(int reg1, int reg2) {
void LIR_Address::verify() const {
assert(base()->is_cpu_register(), "wrong base operand");
assert(index()->is_illegal() || index()->is_double_cpu() || index()->is_single_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
"wrong type for addresses");
}
#endif // PRODUCT
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 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
@@ -52,12 +52,12 @@ void LIR_Address::verify() const {
// be handled by the back-end or will be rejected if not.
#ifdef _LP64
assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
"wrong type for addresses");
#else
assert(base()->is_single_cpu(), "wrong base operand");
assert(index()->is_illegal() || index()->is_single_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_INT || base()->type() == T_METADATA,
assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_INT || base()->type() == T_METADATA,
"wrong type for addresses");
#endif
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -52,12 +52,12 @@ void LIR_Address::verify() const {
#ifdef _LP64
assert(base()->is_cpu_register(), "wrong base operand");
assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
"wrong type for addresses");
#else
assert(base()->is_single_cpu(), "wrong base operand");
assert(index()->is_illegal() || index()->is_single_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_INT || base()->type() == T_METADATA,
assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_INT || base()->type() == T_METADATA,
"wrong type for addresses");
#endif
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -51,7 +51,7 @@ LIR_Opr LIR_OprFact::double_fpu(int reg1, int reg2) {
void LIR_Address::verify() const {
assert(base()->is_cpu_register(), "wrong base operand");
assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
"wrong type for addresses");
}
#endif // PRODUCT
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 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
@@ -62,12 +62,12 @@ void LIR_Address::verify() const {
#ifdef _LP64
assert(base()->is_cpu_register(), "wrong base operand");
assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
"wrong type for addresses");
#else
assert(base()->is_single_cpu(), "wrong base operand");
assert(index()->is_illegal() || index()->is_single_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_INT || base()->type() == T_METADATA,
assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || base()->type() == T_INT || base()->type() == T_METADATA,
"wrong type for addresses");
#endif
}
@@ -1315,8 +1315,12 @@ void LIRGenerator::do_isPrimitive(Intrinsic* x) {
// Example: Thread.currentThread()
void LIRGenerator::do_currentThread(Intrinsic* x) {
assert(x->number_of_arguments() == 0, "wrong type");
LIR_Opr temp = new_register(T_ADDRESS);
LIR_Opr reg = rlock_result(x);
__ move_wide(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg);
__ move(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_ADDRESS), temp);
// threadObj = ((OopHandle)_threadObj)->resolve();
access_load(IN_NATIVE, T_OBJECT,
LIR_OprFact::address(new LIR_Address(temp, T_OBJECT)), reg);
}


@@ -58,7 +58,6 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) :

// Root scanning phases
_gc_par_phases[ThreadRoots] = new WorkerDataArray<double>("ThreadRoots", "Thread Roots (ms):", max_gc_threads);
_gc_par_phases[UniverseRoots] = new WorkerDataArray<double>("UniverseRoots", "Universe Roots (ms):", max_gc_threads);
_gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>("ObjectSynchronizerRoots", "ObjectSynchronizer Roots (ms):", max_gc_threads);
_gc_par_phases[CLDGRoots] = new WorkerDataArray<double>("CLDGRoots", "CLDG Roots (ms):", max_gc_threads);
AOT_ONLY(_gc_par_phases[AOTCodeRoots] = new WorkerDataArray<double>("AOTCodeRoots", "AOT Root Scan (ms):", max_gc_threads);)
@@ -48,7 +48,6 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
GCWorkerStart,
ExtRootScan,
ThreadRoots,
UniverseRoots,
ObjectSynchronizerRoots,
CLDGRoots,
AOT_ONLY(AOTCodeRoots COMMA)
@@ -43,7 +43,6 @@
#include "gc/shared/oopStorageSetParState.inline.hpp"
#include "gc/shared/referenceProcessor.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/universe.hpp"
#include "runtime/mutex.hpp"
#include "utilities/macros.hpp"

@@ -181,13 +180,6 @@ void G1RootProcessor::process_vm_roots(G1RootClosures* closures,
uint worker_id) {
OopClosure* strong_roots = closures->strong_oops();

{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_id);
if (_process_strong_tasks.try_claim_task(G1RP_PS_Universe_oops_do)) {
Universe::oops_do(strong_roots);
}
}

{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ObjectSynchronizerRoots, worker_id);
if (_process_strong_tasks.try_claim_task(G1RP_PS_ObjectSynchronizer_oops_do)) {
@@ -2008,10 +2008,6 @@ static void mark_from_roots_work(ParallelRootType::Value root_type, uint worker_
PCMarkAndPushClosure mark_and_push_closure(cm);

switch (root_type) {
case ParallelRootType::universe:
Universe::oops_do(&mark_and_push_closure);
break;

case ParallelRootType::object_synchronizer:
ObjectSynchronizer::oops_do(&mark_and_push_closure);
break;
@@ -2225,7 +2221,6 @@ void PSParallelCompact::adjust_roots(ParCompactionManager* cm) {
PCAdjustPointerClosure oop_closure(cm);

// General strong roots.
Universe::oops_do(&oop_closure);
Threads::oops_do(&oop_closure, NULL);
ObjectSynchronizer::oops_do(&oop_closure);
OopStorageSet::strong_oops_do(&oop_closure);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
@@ -34,7 +34,6 @@ class ParallelRootType : public AllStatic {
// The order reflects the order these roots are to be processed,
// We do not want any holes in the enum as we enumerate these values by incrementing them.
enum Value {
universe,
object_synchronizer,
class_loader_data,
code_cache,
@@ -92,10 +92,6 @@ static void scavenge_roots_work(ParallelRootType::Value root_type, uint worker_i
PSPromoteRootsClosure roots_to_old_closure(pm);

switch (root_type) {
case ParallelRootType::universe:
Universe::oops_do(&roots_closure);
break;

case ParallelRootType::object_synchronizer:
ObjectSynchronizer::oops_do(&roots_closure);
break;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 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
@@ -141,6 +141,7 @@ Node* BarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) con
bool control_dependent = (decorators & C2_CONTROL_DEPENDENT_LOAD) != 0;
bool unknown_control = (decorators & C2_UNKNOWN_CONTROL_LOAD) != 0;
bool unsafe = (decorators & C2_UNSAFE_ACCESS) != 0;
bool immutable = (decorators & C2_IMMUTABLE_MEMORY) != 0;

bool in_native = (decorators & IN_NATIVE) != 0;

@@ -153,10 +154,14 @@ Node* BarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) con
GraphKit* kit = parse_access.kit();
Node* control = control_dependent ? kit->control() : NULL;

if (in_native) {
load = kit->make_load(control, adr, val_type, access.type(), mo, dep,
requires_atomic_access, unaligned,
if (immutable) {
assert(!requires_atomic_access, "can't ensure atomicity");
Compile* C = Compile::current();
Node* mem = kit->immutable_memory();
load = LoadNode::make(kit->gvn(), control, mem, adr,
adr_type, val_type, access.type(), mo, dep, unaligned,
mismatched, unsafe, access.barrier_data());
load = kit->gvn().transform(load);
} else {
load = kit->make_load(control, adr, val_type, access.type(), adr_type, mo,
dep, requires_atomic_access, unaligned, mismatched, unsafe,
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 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
@@ -54,6 +54,8 @@ const DecoratorSet C2_READ_ACCESS = DECORATOR_LAST << 8;
const DecoratorSet C2_TIGHTLY_COUPLED_ALLOC = DECORATOR_LAST << 9;
// Loads and stores from an arraycopy being optimized
const DecoratorSet C2_ARRAY_COPY = DECORATOR_LAST << 10;
// Loads from immutable memory
const DecoratorSet C2_IMMUTABLE_MEMORY = DECORATOR_LAST << 11;

class Compile;
class ConnectionGraph;
@@ -817,10 +817,6 @@ void GenCollectedHeap::process_roots(StrongRootsScope* scope,
bool is_par = scope->n_threads() > 1;
Threads::possibly_parallel_oops_do(is_par, strong_roots, roots_from_code_p);

if (_process_strong_tasks->try_claim_task(GCH_PS_Universe_oops_do)) {
Universe::oops_do(strong_roots);
}

if (_process_strong_tasks->try_claim_task(GCH_PS_ObjectSynchronizer_oops_do)) {
ObjectSynchronizer::oops_do(strong_roots);
}
@@ -105,7 +105,6 @@ class GenCollectedHeap : public CollectedHeap {

// The set of potentially parallel tasks in root scanning.
enum GCH_strong_roots_tasks {
GCH_PS_Universe_oops_do,
GCH_PS_ObjectSynchronizer_oops_do,
GCH_PS_OopStorageSet_oops_do,
GCH_PS_ClassLoaderDataGraph_oops_do,
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
@@ -37,7 +37,7 @@ class OopStorageSet : public AllStatic {

public:
// Must be updated when new OopStorages are introduced
static const uint strong_count = 2;
static const uint strong_count = 3;
static const uint weak_count = 4 JFR_ONLY(+ 1);
static const uint all_count = strong_count + weak_count;

@@ -37,7 +37,6 @@ class outputStream;
f(CNT_PREFIX ## TotalWork, DESC_PREFIX "<total>") \
f(CNT_PREFIX ## ThreadRoots, DESC_PREFIX "Thread Roots") \
f(CNT_PREFIX ## CodeCacheRoots, DESC_PREFIX "Code Cache Roots") \
f(CNT_PREFIX ## UniverseRoots, DESC_PREFIX "Universe Roots") \
f(CNT_PREFIX ## VMStrongRoots, DESC_PREFIX "VM Strong Roots") \
f(CNT_PREFIX ## VMWeakRoots, DESC_PREFIX "VM Weak Roots") \
f(CNT_PREFIX ## ObjectSynchronizerRoots, DESC_PREFIX "Synchronizer Roots") \
@@ -37,7 +37,6 @@
#include "gc/shenandoah/shenandoahVMOperations.hpp"
#include "memory/iterator.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "runtime/thread.hpp"

ShenandoahSerialRoot::ShenandoahSerialRoot(ShenandoahSerialRoot::OopsDo oops_do,
@@ -53,12 +52,10 @@ void ShenandoahSerialRoot::oops_do(OopClosure* cl, uint worker_id) {
}

ShenandoahSerialRoots::ShenandoahSerialRoots(ShenandoahPhaseTimings::Phase phase) :
_universe_root(&Universe::oops_do, phase, ShenandoahPhaseTimings::UniverseRoots),
_object_synchronizer_root(&ObjectSynchronizer::oops_do, phase, ShenandoahPhaseTimings::ObjectSynchronizerRoots) {
}

void ShenandoahSerialRoots::oops_do(OopClosure* cl, uint worker_id) {
_universe_root.oops_do(cl, worker_id);
_object_synchronizer_root.oops_do(cl, worker_id);
}

@@ -51,7 +51,6 @@ class ShenandoahSerialRoot {

class ShenandoahSerialRoots {
private:
ShenandoahSerialRoot _universe_root;
ShenandoahSerialRoot _object_synchronizer_root;
public:
ShenandoahSerialRoots(ShenandoahPhaseTimings::Phase phase);
@@ -37,7 +37,6 @@
#include "gc/shared/oopStorage.inline.hpp"
#include "gc/shared/oopStorageSet.hpp"
#include "gc/shared/weakProcessor.inline.hpp"
#include "memory/universe.hpp"
#include "runtime/thread.hpp"
#include "utilities/debug.hpp"

@@ -75,7 +74,6 @@ void ShenandoahRootVerifier::oops_do(OopClosure* oops) {

if (verify(SerialRoots)) {
shenandoah_assert_safepoint();
Universe::oops_do(oops);
ObjectSynchronizer::oops_do(oops);
}

@@ -119,7 +117,6 @@ void ShenandoahRootVerifier::roots_do(OopClosure* oops) {
CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
ClassLoaderDataGraph::cld_do(&clds);

Universe::oops_do(oops);
JNIHandles::oops_do(oops);
ObjectSynchronizer::oops_do(oops);
Universe::vm_global()->oops_do(oops);
@@ -145,7 +142,6 @@ void ShenandoahRootVerifier::strong_roots_do(OopClosure* oops) {
CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
ClassLoaderDataGraph::roots_cld_do(&clds, NULL);

Universe::oops_do(oops);
JNIHandles::oops_do(oops);
ObjectSynchronizer::oops_do(oops);
Universe::vm_global()->oops_do(oops);
@@ -54,7 +54,6 @@
static const ZStatSubPhase ZSubPhasePauseRootsSetup("Pause Roots Setup");
static const ZStatSubPhase ZSubPhasePauseRoots("Pause Roots");
static const ZStatSubPhase ZSubPhasePauseRootsTeardown("Pause Roots Teardown");
static const ZStatSubPhase ZSubPhasePauseRootsUniverse("Pause Roots Universe");
static const ZStatSubPhase ZSubPhasePauseRootsObjectSynchronizer("Pause Roots ObjectSynchronizer");
static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport");
static const ZStatSubPhase ZSubPhasePauseRootsVMThread("Pause Roots VM Thread");
@@ -185,7 +184,6 @@ void ZJavaThreadsIterator::threads_do(ThreadClosure* cl) {
ZRootsIterator::ZRootsIterator(bool visit_jvmti_weak_export) :
_visit_jvmti_weak_export(visit_jvmti_weak_export),
_java_threads_iter(),
_universe(this),
_object_synchronizer(this),
_jvmti_weak_export(this),
_vm_thread(this),
@@ -213,11 +211,6 @@ ZRootsIterator::~ZRootsIterator() {
COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::update_pointers());
}

void ZRootsIterator::do_universe(ZRootsIteratorClosure* cl) {
ZStatTimer timer(ZSubPhasePauseRootsUniverse);
Universe::oops_do(cl);
}

void ZRootsIterator::do_object_synchronizer(ZRootsIteratorClosure* cl) {
ZStatTimer timer(ZSubPhasePauseRootsObjectSynchronizer);
ObjectSynchronizer::oops_do(cl);
@@ -248,7 +241,6 @@ void ZRootsIterator::do_code_cache(ZRootsIteratorClosure* cl) {

void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
ZStatTimer timer(ZSubPhasePauseRoots);
_universe.oops_do(cl);
_object_synchronizer.oops_do(cl);
_vm_thread.oops_do(cl);
_java_threads.oops_do(cl);
@@ -110,14 +110,12 @@ class ZRootsIterator {
const bool _visit_jvmti_weak_export;
ZJavaThreadsIterator _java_threads_iter;

void do_universe(ZRootsIteratorClosure* cl);
void do_object_synchronizer(ZRootsIteratorClosure* cl);
void do_jvmti_weak_export(ZRootsIteratorClosure* cl);
void do_vm_thread(ZRootsIteratorClosure* cl);
void do_java_threads(ZRootsIteratorClosure* cl);
void do_code_cache(ZRootsIteratorClosure* cl);

ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_universe> _universe;
ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_object_synchronizer> _object_synchronizer;
ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_jvmti_weak_export> _jvmti_weak_export;
ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_vm_thread> _vm_thread;

0 comments on commit 21b9941

Please sign in to comment.