jdk-24/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp
Coleen Phillimore c1281e6b45 8324678: Replace NULL with nullptr in HotSpot gtests
Reviewed-by: kbarrett, dholmes, jwaters
2024-01-29 17:12:13 +00:00

139 lines
4.0 KiB
C++

/*
* Copyright (c) 2021, 2024, 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 "memory/allocation.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/metaspaceClosure.hpp"
#include "oops/array.hpp"
#include "oops/metadata.hpp"
#include "runtime/javaThread.hpp"
#include "unittest.hpp"
class MyMetaData : public MetaspaceObj {
public:
MyMetaData* _a;
MyMetaData* _b;
MyMetaData() : _a(nullptr), _b(nullptr) {}
MetaspaceObj::Type type() const {
return MetaspaceObj::SymbolType; // Just lie. It doesn't matter in this test
}
const char* internal_name() const {
return "MyMetaData";
}
int size() const {
return align_up((int)sizeof(MyMetaData), wordSize) / wordSize;
};
static bool is_read_only_by_default() {
return true;
}
void metaspace_pointers_do(MetaspaceClosure* it) {
it->push(&_a);
it->push(&_b);
}
};
class MyUniqueMetaspaceClosure : public MetaspaceClosure {
static constexpr int SIZE = 10;
MyMetaData* _visited[SIZE];
int _count;
public:
MyUniqueMetaspaceClosure() {
for (int i = 0; i < SIZE; i++) {
_visited[i] = nullptr;
}
_count = 0;
}
virtual bool do_ref(Ref* ref, bool read_only) {
MyMetaData* ptr = (MyMetaData*)ref->obj();
assert(_count < SIZE, "out of bounds");
_visited[_count++] = ptr;
return true; // recurse
}
bool has_visited(MyMetaData* p) {
for (int i = 0; i < SIZE; i++) {
if (_visited[i] == p) {
return true;
}
}
return false;
}
};
// iterate an Array<MyMetaData*>
TEST_VM(MetaspaceClosure, MSOPointerArrayRef) {
JavaThread* THREAD = JavaThread::current();
ClassLoaderData* cld = ClassLoaderData::the_null_class_loader_data();
Array<MyMetaData*>* array = MetadataFactory::new_array<MyMetaData*>(cld, 4, THREAD);
for (int i = 0; i < array->length(); i++) {
EXPECT_TRUE(array->at(i) == nullptr) << "should be initialized to null";
}
MyMetaData x;
MyMetaData y;
MyMetaData z;
array->at_put(0, &x);
array->at_put(2, &y);
y._a = &z;
MyUniqueMetaspaceClosure closure;
closure.push(&array);
EXPECT_TRUE(closure.has_visited(&x)) << "must be";
EXPECT_TRUE(closure.has_visited(&y)) << "must be";
EXPECT_TRUE(closure.has_visited(&z)) << "must be";
}
// iterate an Array<MyMetaData>
TEST_VM(MetaspaceClosure, MSOArrayRef) {
JavaThread* THREAD = JavaThread::current();
ClassLoaderData* cld = ClassLoaderData::the_null_class_loader_data();
Array<MyMetaData>* array = MetadataFactory::new_array<MyMetaData>(cld, 4, THREAD);
for (int i = 0; i < array->length(); i++) {
EXPECT_TRUE(array->at(i)._a == nullptr) << "should be initialized to null";
EXPECT_TRUE(array->at(i)._b == nullptr) << "should be initialized to null";
}
MyMetaData x;
MyMetaData y;
MyMetaData z;
array->adr_at(0)->_a = &x;
array->adr_at(2)->_b = &y;
y._a = &z;
MyUniqueMetaspaceClosure closure;
closure.push(&array);
EXPECT_TRUE(closure.has_visited(&x)) << "must be";
EXPECT_TRUE(closure.has_visited(&y)) << "must be";
EXPECT_TRUE(closure.has_visited(&z)) << "must be";
}