Merge
This commit is contained in:
commit
b7d9fe6bbb
@ -56,6 +56,7 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
|
|||||||
$(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \
|
$(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \
|
||||||
$(HOTSPOT_TOPDIR)/test/compiler/calls \
|
$(HOTSPOT_TOPDIR)/test/compiler/calls \
|
||||||
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetNamedModule \
|
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetNamedModule \
|
||||||
|
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/IsModifiableModule \
|
||||||
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleReads \
|
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleReads \
|
||||||
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleExportsAndOpens \
|
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleExportsAndOpens \
|
||||||
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleUsesAndProvides \
|
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleUsesAndProvides \
|
||||||
@ -85,6 +86,7 @@ ifeq ($(TOOLCHAIN_TYPE), solstudio)
|
|||||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_liboverflow := -lc
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_liboverflow := -lc
|
||||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libSimpleClassFileLoadHook := -lc
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libSimpleClassFileLoadHook := -lc
|
||||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetNamedModuleTest := -lc
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetNamedModuleTest := -lc
|
||||||
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libIsModifiableModuleTest := -lc
|
||||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleReadsTest := -lc
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleReadsTest := -lc
|
||||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleExportsAndOpensTest := -lc
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleExportsAndOpensTest := -lc
|
||||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleUsesAndProvidesTest := -lc
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleUsesAndProvidesTest := -lc
|
||||||
|
@ -51,6 +51,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread,
|
|||||||
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
|
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
|
||||||
const int aarch64_code_length = VtableStub::pd_code_size_limit(true);
|
const int aarch64_code_length = VtableStub::pd_code_size_limit(true);
|
||||||
VtableStub* s = new(aarch64_code_length) VtableStub(true, vtable_index);
|
VtableStub* s = new(aarch64_code_length) VtableStub(true, vtable_index);
|
||||||
|
// Can be NULL if there is no free space in the code cache.
|
||||||
|
if (s == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
CodeBuffer cb(s->entry_point(), aarch64_code_length);
|
CodeBuffer cb(s->entry_point(), aarch64_code_length);
|
||||||
MacroAssembler* masm = new MacroAssembler(&cb);
|
MacroAssembler* masm = new MacroAssembler(&cb);
|
||||||
|
@ -130,6 +130,7 @@ class CodeBlob_sizes {
|
|||||||
// Iterate over all CodeHeaps
|
// Iterate over all CodeHeaps
|
||||||
#define FOR_ALL_HEAPS(heap) for (GrowableArrayIterator<CodeHeap*> heap = _heaps->begin(); heap != _heaps->end(); ++heap)
|
#define FOR_ALL_HEAPS(heap) for (GrowableArrayIterator<CodeHeap*> heap = _heaps->begin(); heap != _heaps->end(); ++heap)
|
||||||
#define FOR_ALL_NMETHOD_HEAPS(heap) for (GrowableArrayIterator<CodeHeap*> heap = _nmethod_heaps->begin(); heap != _nmethod_heaps->end(); ++heap)
|
#define FOR_ALL_NMETHOD_HEAPS(heap) for (GrowableArrayIterator<CodeHeap*> heap = _nmethod_heaps->begin(); heap != _nmethod_heaps->end(); ++heap)
|
||||||
|
#define FOR_ALL_ALLOCABLE_HEAPS(heap) for (GrowableArrayIterator<CodeHeap*> heap = _allocable_heaps->begin(); heap != _allocable_heaps->end(); ++heap)
|
||||||
|
|
||||||
// Iterate over all CodeBlobs (cb) on the given CodeHeap
|
// Iterate over all CodeBlobs (cb) on the given CodeHeap
|
||||||
#define FOR_ALL_BLOBS(cb, heap) for (CodeBlob* cb = first_blob(heap); cb != NULL; cb = next_blob(heap, cb))
|
#define FOR_ALL_BLOBS(cb, heap) for (CodeBlob* cb = first_blob(heap); cb != NULL; cb = next_blob(heap, cb))
|
||||||
@ -140,10 +141,11 @@ int CodeCache::_number_of_nmethods_with_dependencies = 0;
|
|||||||
bool CodeCache::_needs_cache_clean = false;
|
bool CodeCache::_needs_cache_clean = false;
|
||||||
nmethod* CodeCache::_scavenge_root_nmethods = NULL;
|
nmethod* CodeCache::_scavenge_root_nmethods = NULL;
|
||||||
|
|
||||||
// Initialize array of CodeHeaps
|
// Initialize arrays of CodeHeap subsets
|
||||||
GrowableArray<CodeHeap*>* CodeCache::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<CodeHeap*> (CodeBlobType::All, true);
|
GrowableArray<CodeHeap*>* CodeCache::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<CodeHeap*> (CodeBlobType::All, true);
|
||||||
GrowableArray<CodeHeap*>* CodeCache::_compiled_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<CodeHeap*> (CodeBlobType::All, true);
|
GrowableArray<CodeHeap*>* CodeCache::_compiled_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<CodeHeap*> (CodeBlobType::All, true);
|
||||||
GrowableArray<CodeHeap*>* CodeCache::_nmethod_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<CodeHeap*> (CodeBlobType::All, true);
|
GrowableArray<CodeHeap*>* CodeCache::_nmethod_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<CodeHeap*> (CodeBlobType::All, true);
|
||||||
|
GrowableArray<CodeHeap*>* CodeCache::_allocable_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<CodeHeap*> (CodeBlobType::All, true);
|
||||||
|
|
||||||
void CodeCache::check_heap_sizes(size_t non_nmethod_size, size_t profiled_size, size_t non_profiled_size, size_t cache_size, bool all_set) {
|
void CodeCache::check_heap_sizes(size_t non_nmethod_size, size_t profiled_size, size_t non_profiled_size, size_t cache_size, bool all_set) {
|
||||||
size_t total_size = non_nmethod_size + profiled_size + non_profiled_size;
|
size_t total_size = non_nmethod_size + profiled_size + non_profiled_size;
|
||||||
@ -338,6 +340,7 @@ ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) {
|
|||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Heaps available for allocation
|
||||||
bool CodeCache::heap_available(int code_blob_type) {
|
bool CodeCache::heap_available(int code_blob_type) {
|
||||||
if (!SegmentedCodeCache) {
|
if (!SegmentedCodeCache) {
|
||||||
// No segmentation: use a single code heap
|
// No segmentation: use a single code heap
|
||||||
@ -391,6 +394,9 @@ void CodeCache::add_heap(CodeHeap* heap) {
|
|||||||
if (code_blob_type_accepts_nmethod(type)) {
|
if (code_blob_type_accepts_nmethod(type)) {
|
||||||
_nmethod_heaps->insert_sorted<code_heap_compare>(heap);
|
_nmethod_heaps->insert_sorted<code_heap_compare>(heap);
|
||||||
}
|
}
|
||||||
|
if (code_blob_type_accepts_allocable(type)) {
|
||||||
|
_allocable_heaps->insert_sorted<code_heap_compare>(heap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeCache::add_heap(ReservedSpace rs, const char* name, int code_blob_type) {
|
void CodeCache::add_heap(ReservedSpace rs, const char* name, int code_blob_type) {
|
||||||
@ -620,7 +626,7 @@ nmethod* CodeCache::find_nmethod(void* start) {
|
|||||||
|
|
||||||
void CodeCache::blobs_do(void f(CodeBlob* nm)) {
|
void CodeCache::blobs_do(void f(CodeBlob* nm)) {
|
||||||
assert_locked_or_safepoint(CodeCache_lock);
|
assert_locked_or_safepoint(CodeCache_lock);
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_HEAPS(heap) {
|
||||||
FOR_ALL_BLOBS(cb, *heap) {
|
FOR_ALL_BLOBS(cb, *heap) {
|
||||||
f(cb);
|
f(cb);
|
||||||
}
|
}
|
||||||
@ -663,7 +669,7 @@ void CodeCache::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurre
|
|||||||
|
|
||||||
void CodeCache::blobs_do(CodeBlobClosure* f) {
|
void CodeCache::blobs_do(CodeBlobClosure* f) {
|
||||||
assert_locked_or_safepoint(CodeCache_lock);
|
assert_locked_or_safepoint(CodeCache_lock);
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
FOR_ALL_BLOBS(cb, *heap) {
|
FOR_ALL_BLOBS(cb, *heap) {
|
||||||
if (cb->is_alive()) {
|
if (cb->is_alive()) {
|
||||||
f->do_code_blob(cb);
|
f->do_code_blob(cb);
|
||||||
@ -960,7 +966,7 @@ address CodeCache::high_bound(int code_blob_type) {
|
|||||||
|
|
||||||
size_t CodeCache::capacity() {
|
size_t CodeCache::capacity() {
|
||||||
size_t cap = 0;
|
size_t cap = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
cap += (*heap)->capacity();
|
cap += (*heap)->capacity();
|
||||||
}
|
}
|
||||||
return cap;
|
return cap;
|
||||||
@ -973,7 +979,7 @@ size_t CodeCache::unallocated_capacity(int code_blob_type) {
|
|||||||
|
|
||||||
size_t CodeCache::unallocated_capacity() {
|
size_t CodeCache::unallocated_capacity() {
|
||||||
size_t unallocated_cap = 0;
|
size_t unallocated_cap = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
unallocated_cap += (*heap)->unallocated_capacity();
|
unallocated_cap += (*heap)->unallocated_capacity();
|
||||||
}
|
}
|
||||||
return unallocated_cap;
|
return unallocated_cap;
|
||||||
@ -981,7 +987,7 @@ size_t CodeCache::unallocated_capacity() {
|
|||||||
|
|
||||||
size_t CodeCache::max_capacity() {
|
size_t CodeCache::max_capacity() {
|
||||||
size_t max_cap = 0;
|
size_t max_cap = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
max_cap += (*heap)->max_capacity();
|
max_cap += (*heap)->max_capacity();
|
||||||
}
|
}
|
||||||
return max_cap;
|
return max_cap;
|
||||||
@ -1007,7 +1013,7 @@ double CodeCache::reverse_free_ratio(int code_blob_type) {
|
|||||||
|
|
||||||
size_t CodeCache::bytes_allocated_in_freelists() {
|
size_t CodeCache::bytes_allocated_in_freelists() {
|
||||||
size_t allocated_bytes = 0;
|
size_t allocated_bytes = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
allocated_bytes += (*heap)->allocated_in_freelist();
|
allocated_bytes += (*heap)->allocated_in_freelist();
|
||||||
}
|
}
|
||||||
return allocated_bytes;
|
return allocated_bytes;
|
||||||
@ -1015,7 +1021,7 @@ size_t CodeCache::bytes_allocated_in_freelists() {
|
|||||||
|
|
||||||
int CodeCache::allocated_segments() {
|
int CodeCache::allocated_segments() {
|
||||||
int number_of_segments = 0;
|
int number_of_segments = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
number_of_segments += (*heap)->allocated_segments();
|
number_of_segments += (*heap)->allocated_segments();
|
||||||
}
|
}
|
||||||
return number_of_segments;
|
return number_of_segments;
|
||||||
@ -1023,7 +1029,7 @@ int CodeCache::allocated_segments() {
|
|||||||
|
|
||||||
size_t CodeCache::freelists_length() {
|
size_t CodeCache::freelists_length() {
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
length += (*heap)->freelist_length();
|
length += (*heap)->freelist_length();
|
||||||
}
|
}
|
||||||
return length;
|
return length;
|
||||||
@ -1354,7 +1360,7 @@ void CodeCache::report_codemem_full(int code_blob_type, bool print) {
|
|||||||
|
|
||||||
void CodeCache::print_memory_overhead() {
|
void CodeCache::print_memory_overhead() {
|
||||||
size_t wasted_bytes = 0;
|
size_t wasted_bytes = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
CodeHeap* curr_heap = *heap;
|
CodeHeap* curr_heap = *heap;
|
||||||
for (CodeBlob* cb = (CodeBlob*)curr_heap->first(); cb != NULL; cb = (CodeBlob*)curr_heap->next(cb)) {
|
for (CodeBlob* cb = (CodeBlob*)curr_heap->first(); cb != NULL; cb = (CodeBlob*)curr_heap->next(cb)) {
|
||||||
HeapBlock* heap_block = ((HeapBlock*)cb) - 1;
|
HeapBlock* heap_block = ((HeapBlock*)cb) - 1;
|
||||||
@ -1400,7 +1406,7 @@ void CodeCache::print_internals() {
|
|||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
if ((_nmethod_heaps->length() >= 1) && Verbose) {
|
if ((_nmethod_heaps->length() >= 1) && Verbose) {
|
||||||
tty->print_cr("-- %s --", (*heap)->name());
|
tty->print_cr("-- %s --", (*heap)->name());
|
||||||
}
|
}
|
||||||
@ -1497,7 +1503,7 @@ void CodeCache::print() {
|
|||||||
CodeBlob_sizes live;
|
CodeBlob_sizes live;
|
||||||
CodeBlob_sizes dead;
|
CodeBlob_sizes dead;
|
||||||
|
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
FOR_ALL_BLOBS(cb, *heap) {
|
FOR_ALL_BLOBS(cb, *heap) {
|
||||||
if (!cb->is_alive()) {
|
if (!cb->is_alive()) {
|
||||||
dead.add(cb);
|
dead.add(cb);
|
||||||
@ -1523,7 +1529,7 @@ void CodeCache::print() {
|
|||||||
int number_of_blobs = 0;
|
int number_of_blobs = 0;
|
||||||
int number_of_oop_maps = 0;
|
int number_of_oop_maps = 0;
|
||||||
int map_size = 0;
|
int map_size = 0;
|
||||||
FOR_ALL_NMETHOD_HEAPS(heap) {
|
FOR_ALL_ALLOCABLE_HEAPS(heap) {
|
||||||
FOR_ALL_BLOBS(cb, *heap) {
|
FOR_ALL_BLOBS(cb, *heap) {
|
||||||
if (cb->is_alive()) {
|
if (cb->is_alive()) {
|
||||||
number_of_blobs++;
|
number_of_blobs++;
|
||||||
|
@ -85,6 +85,7 @@ class CodeCache : AllStatic {
|
|||||||
static GrowableArray<CodeHeap*>* _heaps;
|
static GrowableArray<CodeHeap*>* _heaps;
|
||||||
static GrowableArray<CodeHeap*>* _compiled_heaps;
|
static GrowableArray<CodeHeap*>* _compiled_heaps;
|
||||||
static GrowableArray<CodeHeap*>* _nmethod_heaps;
|
static GrowableArray<CodeHeap*>* _nmethod_heaps;
|
||||||
|
static GrowableArray<CodeHeap*>* _allocable_heaps;
|
||||||
|
|
||||||
static address _low_bound; // Lower bound of CodeHeap addresses
|
static address _low_bound; // Lower bound of CodeHeap addresses
|
||||||
static address _high_bound; // Upper bound of CodeHeap addresses
|
static address _high_bound; // Upper bound of CodeHeap addresses
|
||||||
@ -237,6 +238,11 @@ class CodeCache : AllStatic {
|
|||||||
return type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled;
|
return type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool code_blob_type_accepts_allocable(int type) {
|
||||||
|
return type <= CodeBlobType::All;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns the CodeBlobType for the given compilation level
|
// Returns the CodeBlobType for the given compilation level
|
||||||
static int get_code_blob_type(int comp_level) {
|
static int get_code_blob_type(int comp_level) {
|
||||||
if (comp_level == CompLevel_none ||
|
if (comp_level == CompLevel_none ||
|
||||||
|
@ -1557,7 +1557,7 @@ void CompileBroker::compiler_thread_loop() {
|
|||||||
|
|
||||||
// First thread to get here will initialize the compiler interface
|
// First thread to get here will initialize the compiler interface
|
||||||
|
|
||||||
if (!ciObjectFactory::is_initialized()) {
|
{
|
||||||
ASSERT_IN_VM;
|
ASSERT_IN_VM;
|
||||||
MutexLocker only_one (CompileThread_lock, thread);
|
MutexLocker only_one (CompileThread_lock, thread);
|
||||||
if (!ciObjectFactory::is_initialized()) {
|
if (!ciObjectFactory::is_initialized()) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,6 +26,7 @@ package MyPackage;
|
|||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @summary Verifies the JVMTI GetNamedModule API
|
* @summary Verifies the JVMTI GetNamedModule API
|
||||||
|
* @modules jdk.jdi
|
||||||
* @compile GetNamedModuleTest.java
|
* @compile GetNamedModuleTest.java
|
||||||
* @run main/othervm/native -agentlib:GetNamedModuleTest MyPackage.GetNamedModuleTest
|
* @run main/othervm/native -agentlib:GetNamedModuleTest MyPackage.GetNamedModuleTest
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package MyPackage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @summary Verifies the JVMTI IsModifiableModule API
|
||||||
|
* @modules jdk.jdi
|
||||||
|
* @compile IsModifiableModuleTest.java
|
||||||
|
* @run main/othervm/native -agentlib:IsModifiableModuleTest MyPackage.IsModifiableModuleTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class IsModifiableModuleTest {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("IsModifiableModuleTest");
|
||||||
|
} catch (UnsatisfiedLinkError ule) {
|
||||||
|
System.err.println("Could not load IsModifiableModuleTest library");
|
||||||
|
System.err.println("java.library.path: "
|
||||||
|
+ System.getProperty("java.library.path"));
|
||||||
|
throw ule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
native static int check();
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
int status = check();
|
||||||
|
if (status != 0) {
|
||||||
|
throw new RuntimeException("Non-zero status returned from the agent: " + status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "jvmti.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JNI_ENV_ARG
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define JNI_ENV_ARG(x, y) y
|
||||||
|
#define JNI_ENV_PTR(x) x
|
||||||
|
#else
|
||||||
|
#define JNI_ENV_ARG(x,y) x, y
|
||||||
|
#define JNI_ENV_PTR(x) (*x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TranslateError(err) "JVMTI error"
|
||||||
|
|
||||||
|
#define PASSED 0
|
||||||
|
#define FAILED 2
|
||||||
|
|
||||||
|
static const char *EXC_CNAME = "java/lang/AssertionError";
|
||||||
|
|
||||||
|
static jvmtiEnv *jvmti = NULL;
|
||||||
|
static jint result = PASSED;
|
||||||
|
static jboolean printdump = JNI_FALSE;
|
||||||
|
|
||||||
|
static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
|
||||||
|
|
||||||
|
JNIEXPORT
|
||||||
|
jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
|
||||||
|
return Agent_Initialize(jvm, options, reserved);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT
|
||||||
|
jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
|
||||||
|
return Agent_Initialize(jvm, options, reserved);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT
|
||||||
|
jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
|
||||||
|
return JNI_VERSION_1_8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
|
||||||
|
jint res;
|
||||||
|
|
||||||
|
if (options != NULL && strcmp(options, "printdump") == 0) {
|
||||||
|
printdump = JNI_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
|
||||||
|
JVMTI_VERSION_9);
|
||||||
|
if (res != JNI_OK || jvmti == NULL) {
|
||||||
|
printf(" Error: wrong result of a valid call to GetEnv!\n");
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JNI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
jclass find_class(JNIEnv *env, const char* cname) {
|
||||||
|
jclass cls = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, cname));
|
||||||
|
|
||||||
|
if (cls == NULL) {
|
||||||
|
printf("find_class: Error: FindClass(env, \"%s\") returned NULL\n", cname);
|
||||||
|
}
|
||||||
|
return cls;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
jint throw_exc(JNIEnv *env, char *msg) {
|
||||||
|
jclass exc_class = find_class(env, EXC_CNAME);
|
||||||
|
|
||||||
|
if (exc_class == NULL) {
|
||||||
|
printf("throw_exc: Error in find_class(env, \"%s\")\n", EXC_CNAME);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static jobject get_module_by_class_name(JNIEnv *env, const char* cname) {
|
||||||
|
jobject module = NULL;
|
||||||
|
jclass cls = find_class(env, cname);
|
||||||
|
|
||||||
|
printf(">>> getting module by class name: \"%s\"\n", cname);
|
||||||
|
if (cls == NULL) {
|
||||||
|
printf("get_module_by_class_name: Error in find_class(env, \"%s\")\n", cname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
module = JNI_ENV_PTR(env)->GetModule(JNI_ENV_ARG(env, cls));
|
||||||
|
if (module == NULL) {
|
||||||
|
printf("get_module_by_class_name: Error in GetModule for class \"%s\"\n", cname);
|
||||||
|
}
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
jint check_is_modifiable_error_codes(jobject module, jobject not_a_module) {
|
||||||
|
jvmtiError err = JVMTI_ERROR_NONE;
|
||||||
|
jboolean is_modifiable = JNI_FALSE;
|
||||||
|
|
||||||
|
printf(">>> passing a bad module argument to JVMTI IsModifiableModule\n");
|
||||||
|
err = (*jvmti)->IsModifiableModule(jvmti, not_a_module, &is_modifiable);
|
||||||
|
if (err != JVMTI_ERROR_INVALID_MODULE) {
|
||||||
|
printf(" Error #EC0: Did not get expected INVALID_MODULE error code from"
|
||||||
|
" IsModifiableModule: %s (%d)\n", TranslateError(err), err);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
printf(">>> passing NULL module argument to JVMTI IsModifiableModule\n");
|
||||||
|
err = (*jvmti)->IsModifiableModule(jvmti, NULL, &is_modifiable);
|
||||||
|
if (err != JVMTI_ERROR_NULL_POINTER) {
|
||||||
|
printf(" Error #EC1: Did not get expected NULL_POINTER error code from"
|
||||||
|
" IsModifiableModule: %s (%d)\n", TranslateError(err), err);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
printf(">>> passing NULL status pointer to JVMTI IsModifiableModule\n");
|
||||||
|
err = (*jvmti)->IsModifiableModule(jvmti, module, NULL);
|
||||||
|
if (err != JVMTI_ERROR_NULL_POINTER) {
|
||||||
|
printf(" Error #EC2: Did not get expected NULL_POINTER error code from"
|
||||||
|
" IsModifiableModule: %s (%d)\n", TranslateError(err), err);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
return PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
jint check_is_modifiable(jobject module) {
|
||||||
|
jvmtiError err = JVMTI_ERROR_NONE;
|
||||||
|
jboolean is_modifiable = JNI_FALSE;
|
||||||
|
|
||||||
|
printf(">>> checking module %p is modifiable\n", module);
|
||||||
|
err = (*jvmti)->IsModifiableModule(jvmti, module, &is_modifiable);
|
||||||
|
if (err != JVMTI_ERROR_NONE) {
|
||||||
|
printf(" Error in IsModifiableModule for module %p: %s (%d)\n",
|
||||||
|
module, TranslateError(err), err);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
if (is_modifiable == JNI_FALSE) {
|
||||||
|
printf(" unexpected non-modifiable status for module: %p\n", module);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
return PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_MyPackage_IsModifiableModuleTest_check(JNIEnv *env, jclass cls) {
|
||||||
|
jobject module = NULL;
|
||||||
|
|
||||||
|
if (jvmti == NULL) {
|
||||||
|
throw_exc(env, "JVMTI client was not properly loaded!\n");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n*** Testing IsModifiableModule ***\n\n");
|
||||||
|
|
||||||
|
if (check_is_modifiable_error_codes(module, cls) == FAILED) {
|
||||||
|
throw_exc(env, "check #MM0: failed to return expected error code from "
|
||||||
|
"a bad call to JVMTI IsModifiableModule");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
module = get_module_by_class_name(env, "java/lang/Class");
|
||||||
|
if (check_is_modifiable(module) == FAILED) {
|
||||||
|
throw_exc(env, "check #MM1: failed to return modifiable module status");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
module = get_module_by_class_name(env, "com/sun/jdi/VirtualMachine");
|
||||||
|
if (check_is_modifiable(module) == FAILED) {
|
||||||
|
throw_exc(env, "check #MM2: failed to return modifiable module status");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
module = get_module_by_class_name(env, "MyPackage/IsModifiableModuleTest");
|
||||||
|
if (check_is_modifiable(module) == FAILED) {
|
||||||
|
throw_exc(env, "check #MM3: failed to return modifiable module status");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user