c1281e6b45
Reviewed-by: kbarrett, dholmes, jwaters
139 lines
4.0 KiB
C++
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";
|
|
}
|