mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 21:35:25 +00:00
Merge
This commit is contained in:
commit
cbbe8e8669
@ -618,7 +618,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||
DirtyCardQueue::byte_offset_of_buf()));
|
||||
|
||||
AddressLiteral cardtable((address)ct->byte_map_base);
|
||||
AddressLiteral cardtable((address)ct->byte_map_base, relocInfo::none);
|
||||
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
|
||||
|
||||
// save at least the registers that need saving if the runtime is called
|
||||
@ -645,7 +645,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
// Note: there is a comment in x86 code about not using
|
||||
// ExternalAddress / lea, due to relocation not working
|
||||
// properly for that address. Should be OK for arm, where we
|
||||
// explicitly specify that 'cartable' has a relocInfo::none
|
||||
// explicitly specify that 'cardtable' has a relocInfo::none
|
||||
// type.
|
||||
__ lea(r_card_base_1, cardtable);
|
||||
__ add(r_card_addr_0, r_card_base_1, AsmOperand(r_obj_0, lsr, CardTableModRefBS::card_shift));
|
||||
|
||||
@ -70,18 +70,17 @@ JNIEXPORT jint JNICALL Java_jdk_tools_jaotc_jnilibelf_JNILibELFAPI_elf_1version
|
||||
*/
|
||||
|
||||
static jlong getNativeAddress(JNIEnv* env, jobject ptrObj) {
|
||||
jclass ptrClass;
|
||||
jfieldID fidNumber;
|
||||
jlong nativeAddress = -1;
|
||||
assert (ptrObj != NULL);
|
||||
assert (ptrObj != NULL);
|
||||
// Get a reference to ptr object's class
|
||||
ptrClass = (*env)->GetObjectClass(env, ptrObj);
|
||||
|
||||
// Get the Field ID of the instance variables "address"
|
||||
fidNumber = (*env)->GetFieldID(env, ptrClass, "address", "J");
|
||||
if (fidNumber != NULL) {
|
||||
// Get the long given the Field ID
|
||||
nativeAddress = (*env)->GetLongField(env, ptrObj, fidNumber);
|
||||
jclass ptrClass = (*env)->GetObjectClass(env, ptrObj);
|
||||
if (ptrClass != NULL) {
|
||||
// Get the Field ID of the instance variables "address"
|
||||
jfieldID fidNumber = (*env)->GetFieldID(env, ptrClass, "address", "J");
|
||||
if (fidNumber != NULL) {
|
||||
// Get the long given the Field ID
|
||||
nativeAddress = (*env)->GetLongField(env, ptrObj, fidNumber);
|
||||
}
|
||||
}
|
||||
// fprintf(stderr, "Native address : %lx\n", nativeAddress);
|
||||
return nativeAddress;
|
||||
@ -91,10 +90,15 @@ static jlong getNativeAddress(JNIEnv* env, jobject ptrObj) {
|
||||
* Box the nativeAddress as a Pointer object.
|
||||
*/
|
||||
static jobject makePointerObject(JNIEnv* env, jlong nativeAddr) {
|
||||
jobject retObj = NULL;
|
||||
jclass ptrClass = (*env)->FindClass(env, "jdk/tools/jaotc/jnilibelf/Pointer");
|
||||
// Call back constructor to allocate a Pointer object, with an int argument
|
||||
jmethodID constructorId = (*env)->GetMethodID(env, ptrClass, "<init>", "(J)V");
|
||||
jobject retObj = (*env)->NewObject(env, ptrClass, constructorId, nativeAddr);
|
||||
if (ptrClass != NULL) {
|
||||
// Call back constructor to allocate a Pointer object, with an int argument
|
||||
jmethodID constructorId = (*env)->GetMethodID(env, ptrClass, "<init>", "(J)V");
|
||||
if (constructorId != NULL) {
|
||||
retObj = (*env)->NewObject(env, ptrClass, constructorId, nativeAddr);
|
||||
}
|
||||
}
|
||||
return retObj;
|
||||
}
|
||||
|
||||
|
||||
@ -613,7 +613,7 @@ class LIR_OprFact: public AllStatic {
|
||||
// Platform dependant.
|
||||
static LIR_Opr double_fpu(int reg1, int reg2 = -1 /*fnoreg*/);
|
||||
|
||||
#ifdef __SOFTFP__
|
||||
#ifdef ARM32
|
||||
static LIR_Opr single_softfp(int reg) {
|
||||
return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
|
||||
LIR_OprDesc::float_type |
|
||||
@ -627,7 +627,7 @@ class LIR_OprFact: public AllStatic {
|
||||
LIR_OprDesc::cpu_register |
|
||||
LIR_OprDesc::double_size);
|
||||
}
|
||||
#endif // __SOFTFP__
|
||||
#endif // ARM32
|
||||
|
||||
#if defined(X86)
|
||||
static LIR_Opr single_xmm(int reg) {
|
||||
|
||||
@ -157,6 +157,12 @@ class ValueNumberingVisitor: public InstructionVisitor {
|
||||
void do_UnsafePutRaw (UnsafePutRaw* x) { kill_memory(); }
|
||||
void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); }
|
||||
void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { kill_memory(); }
|
||||
void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ }
|
||||
void do_UnsafeGetObject(UnsafeGetObject* x) {
|
||||
if (x->is_volatile()) { // the JMM requires this
|
||||
kill_memory();
|
||||
}
|
||||
}
|
||||
void do_Intrinsic (Intrinsic* x) { if (!x->preserves_state()) kill_memory(); }
|
||||
|
||||
void do_Phi (Phi* x) { /* nothing to do */ }
|
||||
@ -197,8 +203,6 @@ class ValueNumberingVisitor: public InstructionVisitor {
|
||||
void do_OsrEntry (OsrEntry* x) { /* nothing to do */ }
|
||||
void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }
|
||||
void do_RoundFP (RoundFP* x) { /* nothing to do */ }
|
||||
void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ }
|
||||
void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }
|
||||
void do_ProfileCall (ProfileCall* x) { /* nothing to do */ }
|
||||
void do_ProfileReturnType (ProfileReturnType* x) { /* nothing to do */ }
|
||||
void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ };
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -93,7 +93,7 @@ ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Depen
|
||||
_keep_alive((is_anonymous || h_class_loader.is_null()) ? 1 : 0),
|
||||
_metaspace(NULL), _unloading(false), _klasses(NULL),
|
||||
_modules(NULL), _packages(NULL),
|
||||
_claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
|
||||
_claimed(0), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL),
|
||||
_next(NULL), _dependencies(dependencies),
|
||||
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
|
||||
Monitor::_safepoint_check_never)) {
|
||||
@ -112,6 +112,76 @@ void ClassLoaderData::Dependencies::init(TRAPS) {
|
||||
_list_head = oopFactory::new_objectArray(2, CHECK);
|
||||
}
|
||||
|
||||
ClassLoaderData::ChunkedHandleList::~ChunkedHandleList() {
|
||||
Chunk* c = _head;
|
||||
while (c != NULL) {
|
||||
Chunk* next = c->_next;
|
||||
delete c;
|
||||
c = next;
|
||||
}
|
||||
}
|
||||
|
||||
oop* ClassLoaderData::ChunkedHandleList::add(oop o) {
|
||||
if (_head == NULL || _head->_size == Chunk::CAPACITY) {
|
||||
Chunk* next = new Chunk(_head);
|
||||
OrderAccess::release_store_ptr(&_head, next);
|
||||
}
|
||||
oop* handle = &_head->_data[_head->_size];
|
||||
*handle = o;
|
||||
OrderAccess::release_store(&_head->_size, _head->_size + 1);
|
||||
return handle;
|
||||
}
|
||||
|
||||
inline void ClassLoaderData::ChunkedHandleList::oops_do_chunk(OopClosure* f, Chunk* c, const juint size) {
|
||||
for (juint i = 0; i < size; i++) {
|
||||
if (c->_data[i] != NULL) {
|
||||
f->do_oop(&c->_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderData::ChunkedHandleList::oops_do(OopClosure* f) {
|
||||
Chunk* head = (Chunk*) OrderAccess::load_ptr_acquire(&_head);
|
||||
if (head != NULL) {
|
||||
// Must be careful when reading size of head
|
||||
oops_do_chunk(f, head, OrderAccess::load_acquire(&head->_size));
|
||||
for (Chunk* c = head->_next; c != NULL; c = c->_next) {
|
||||
oops_do_chunk(f, c, c->_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
class VerifyContainsOopClosure : public OopClosure {
|
||||
oop* _target;
|
||||
bool _found;
|
||||
|
||||
public:
|
||||
VerifyContainsOopClosure(oop* target) : _target(target), _found(false) {}
|
||||
|
||||
void do_oop(oop* p) {
|
||||
if (p == _target) {
|
||||
_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
void do_oop(narrowOop* p) {
|
||||
// The ChunkedHandleList should not contain any narrowOop
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
bool found() const {
|
||||
return _found;
|
||||
}
|
||||
};
|
||||
|
||||
bool ClassLoaderData::ChunkedHandleList::contains(oop* p) {
|
||||
VerifyContainsOopClosure cl(p);
|
||||
oops_do(&cl);
|
||||
return cl.found();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ClassLoaderData::claim() {
|
||||
if (_claimed == 1) {
|
||||
return false;
|
||||
@ -146,9 +216,9 @@ void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool m
|
||||
|
||||
f->do_oop(&_class_loader);
|
||||
_dependencies.oops_do(f);
|
||||
if (_handles != NULL) {
|
||||
_handles->oops_do(f);
|
||||
}
|
||||
|
||||
_handles.oops_do(f);
|
||||
|
||||
if (klass_closure != NULL) {
|
||||
classes_do(klass_closure);
|
||||
}
|
||||
@ -484,12 +554,6 @@ ClassLoaderData::~ClassLoaderData() {
|
||||
_metaspace = NULL;
|
||||
delete m;
|
||||
}
|
||||
// release the handles
|
||||
if (_handles != NULL) {
|
||||
JNIHandleBlock::release_block(_handles);
|
||||
_handles = NULL;
|
||||
}
|
||||
|
||||
// Clear all the JNI handles for methods
|
||||
// These aren't deallocated and are going to look like a leak, but that's
|
||||
// needed because we can't really get rid of jmethodIDs because we don't
|
||||
@ -563,19 +627,14 @@ Metaspace* ClassLoaderData::metaspace_non_null() {
|
||||
return metaspace;
|
||||
}
|
||||
|
||||
JNIHandleBlock* ClassLoaderData::handles() const { return _handles; }
|
||||
void ClassLoaderData::set_handles(JNIHandleBlock* handles) { _handles = handles; }
|
||||
|
||||
jobject ClassLoaderData::add_handle(Handle h) {
|
||||
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
|
||||
if (handles() == NULL) {
|
||||
set_handles(JNIHandleBlock::allocate_block());
|
||||
}
|
||||
return handles()->allocate_handle(h());
|
||||
return (jobject) _handles.add(h());
|
||||
}
|
||||
|
||||
void ClassLoaderData::remove_handle(jobject h) {
|
||||
_handles->release_handle(h);
|
||||
void ClassLoaderData::remove_handle_unsafe(jobject h) {
|
||||
assert(_handles.contains((oop*) h), "Got unexpected handle " PTR_FORMAT, p2i((oop*) h));
|
||||
*((oop*) h) = NULL;
|
||||
}
|
||||
|
||||
// Add this metadata pointer to be freed when it's safe. This is only during
|
||||
@ -645,7 +704,6 @@ void ClassLoaderData::dump(outputStream * const out) {
|
||||
p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name());
|
||||
if (claimed()) out->print(" claimed ");
|
||||
if (is_unloading()) out->print(" unloading ");
|
||||
out->print(" handles " INTPTR_FORMAT, p2i(handles()));
|
||||
out->cr();
|
||||
if (metaspace_or_null() != NULL) {
|
||||
out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -52,7 +52,6 @@
|
||||
|
||||
class ClassLoaderData;
|
||||
class JNIMethodBlock;
|
||||
class JNIHandleBlock;
|
||||
class Metadebug;
|
||||
class ModuleEntry;
|
||||
class PackageEntry;
|
||||
@ -160,6 +159,34 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
void oops_do(OopClosure* f);
|
||||
};
|
||||
|
||||
class ChunkedHandleList VALUE_OBJ_CLASS_SPEC {
|
||||
struct Chunk : public CHeapObj<mtClass> {
|
||||
static const size_t CAPACITY = 32;
|
||||
|
||||
oop _data[CAPACITY];
|
||||
volatile juint _size;
|
||||
Chunk* _next;
|
||||
|
||||
Chunk(Chunk* c) : _next(c), _size(0) { }
|
||||
};
|
||||
|
||||
Chunk* _head;
|
||||
|
||||
void oops_do_chunk(OopClosure* f, Chunk* c, const juint size);
|
||||
|
||||
public:
|
||||
ChunkedHandleList() : _head(NULL) {}
|
||||
~ChunkedHandleList();
|
||||
|
||||
// Only one thread at a time can add, guarded by ClassLoaderData::metaspace_lock().
|
||||
// However, multiple threads can execute oops_do concurrently with add.
|
||||
oop* add(oop o);
|
||||
#ifdef ASSERT
|
||||
bool contains(oop* p);
|
||||
#endif
|
||||
void oops_do(OopClosure* f);
|
||||
};
|
||||
|
||||
friend class ClassLoaderDataGraph;
|
||||
friend class ClassLoaderDataGraphKlassIteratorAtomic;
|
||||
friend class ClassLoaderDataGraphMetaspaceIterator;
|
||||
@ -185,8 +212,8 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
volatile int _claimed; // true if claimed, for example during GC traces.
|
||||
// To avoid applying oop closure more than once.
|
||||
// Has to be an int because we cas it.
|
||||
JNIHandleBlock* _handles; // Handles to constant pool arrays, Modules, etc, which
|
||||
// have the same life cycle of the corresponding ClassLoader.
|
||||
ChunkedHandleList _handles; // Handles to constant pool arrays, Modules, etc, which
|
||||
// have the same life cycle of the corresponding ClassLoader.
|
||||
|
||||
Klass* volatile _klasses; // The classes defined by the class loader.
|
||||
PackageEntryTable* volatile _packages; // The packages defined by the class loader.
|
||||
@ -217,9 +244,6 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies);
|
||||
~ClassLoaderData();
|
||||
|
||||
JNIHandleBlock* handles() const;
|
||||
void set_handles(JNIHandleBlock* handles);
|
||||
|
||||
// GC interface.
|
||||
void clear_claimed() { _claimed = 0; }
|
||||
bool claimed() const { return _claimed == 1; }
|
||||
@ -312,7 +336,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
const char* loader_name();
|
||||
|
||||
jobject add_handle(Handle h);
|
||||
void remove_handle(jobject h);
|
||||
void remove_handle_unsafe(jobject h);
|
||||
void add_class(Klass* k, bool publicize = true);
|
||||
void remove_class(Klass* k);
|
||||
bool contains_klass(Klass* k);
|
||||
|
||||
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -87,11 +87,11 @@ Handle ModuleEntry::shared_protection_domain() {
|
||||
// Set the shared ProtectionDomain atomically
|
||||
void ModuleEntry::set_shared_protection_domain(ClassLoaderData *loader_data,
|
||||
Handle pd_h) {
|
||||
// Create a JNI handle for the shared ProtectionDomain and save it atomically.
|
||||
// If someone beats us setting the _pd cache, the created JNI handle is destroyed.
|
||||
// Create a handle for the shared ProtectionDomain and save it atomically.
|
||||
// If someone beats us setting the _pd cache, the created handle is destroyed.
|
||||
jobject obj = loader_data->add_handle(pd_h);
|
||||
if (Atomic::cmpxchg_ptr(obj, &_pd, NULL) != NULL) {
|
||||
loader_data->remove_handle(obj);
|
||||
loader_data->remove_handle_unsafe(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -56,6 +56,31 @@
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
|
||||
void JNIHandleMark::push_jni_handle_block() {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
if (thread != NULL) {
|
||||
// Allocate a new block for JNI handles.
|
||||
// Inlined code from jni_PushLocalFrame()
|
||||
JNIHandleBlock* java_handles = ((JavaThread*)thread)->active_handles();
|
||||
JNIHandleBlock* compile_handles = JNIHandleBlock::allocate_block(thread);
|
||||
assert(compile_handles != NULL && java_handles != NULL, "should not be NULL");
|
||||
compile_handles->set_pop_frame_link(java_handles);
|
||||
thread->set_active_handles(compile_handles);
|
||||
}
|
||||
}
|
||||
|
||||
void JNIHandleMark::pop_jni_handle_block() {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
if (thread != NULL) {
|
||||
// Release our JNI handle block
|
||||
JNIHandleBlock* compile_handles = thread->active_handles();
|
||||
JNIHandleBlock* java_handles = compile_handles->pop_frame_link();
|
||||
thread->set_active_handles(java_handles);
|
||||
compile_handles->set_pop_frame_link(NULL);
|
||||
JNIHandleBlock::release_block(compile_handles, thread); // may block
|
||||
}
|
||||
}
|
||||
|
||||
// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
|
||||
#define C2V_VMENTRY(result_type, name, signature) \
|
||||
JNIEXPORT result_type JNICALL c2v_ ## name signature { \
|
||||
@ -89,6 +114,7 @@ oop CompilerToVM::get_jvmci_type(KlassHandle klass, TRAPS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int CompilerToVM::Data::Klass_vtable_start_offset;
|
||||
int CompilerToVM::Data::Klass_vtable_length_offset;
|
||||
|
||||
@ -985,6 +1011,8 @@ C2V_END
|
||||
C2V_VMENTRY(jint, installCode, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject installed_code, jobject speculation_log))
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
JNIHandleMark jni_hm;
|
||||
|
||||
Handle target_handle = JNIHandles::resolve(target);
|
||||
Handle compiled_code_handle = JNIHandles::resolve(compiled_code);
|
||||
CodeBlob* cb = NULL;
|
||||
|
||||
@ -206,4 +206,14 @@ class JavaArgumentUnboxer : public SignatureIterator {
|
||||
inline void do_void() { }
|
||||
};
|
||||
|
||||
class JNIHandleMark : public StackObj {
|
||||
public:
|
||||
JNIHandleMark() { push_jni_handle_block(); }
|
||||
~JNIHandleMark() { pop_jni_handle_block(); }
|
||||
|
||||
private:
|
||||
static void push_jni_handle_block();
|
||||
static void pop_jni_handle_block();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_JVMCI_JVMCI_COMPILER_TO_VM_HPP
|
||||
|
||||
@ -305,6 +305,7 @@
|
||||
static_field(StubRoutines, _crc32c_table_addr, address) \
|
||||
static_field(StubRoutines, _updateBytesCRC32C, address) \
|
||||
static_field(StubRoutines, _updateBytesAdler32, address) \
|
||||
static_field(StubRoutines, _multiplyToLen, address) \
|
||||
static_field(StubRoutines, _squareToLen, address) \
|
||||
static_field(StubRoutines, _mulAdd, address) \
|
||||
static_field(StubRoutines, _montgomeryMultiply, address) \
|
||||
|
||||
@ -20,10 +20,19 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.ClassSearchTest
|
||||
*/
|
||||
|
||||
package jdk.tools.jaotc.test.collect;
|
||||
|
||||
|
||||
import jdk.tools.jaotc.LoadedClass;
|
||||
import jdk.tools.jaotc.collect.*;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -32,45 +41,90 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class ClassSearchTest {
|
||||
@Test(expected = InternalError.class)
|
||||
public void itShouldThrowExceptionIfNoProvidersAvailable() {
|
||||
ClassSearch target = new ClassSearch();
|
||||
SearchPath searchPath = new SearchPath();
|
||||
target.search(list("foo"), searchPath);
|
||||
target.search(list(new SearchFor("foo")), searchPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldFindAProviderForEachEntry() {
|
||||
Set<String> searched = new HashSet<>();
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(new SourceProvider() {
|
||||
@Override
|
||||
public ClassSource findSource(String name, SearchPath searchPath) {
|
||||
target.addProvider(provider("", (name, searchPath) -> {
|
||||
searched.add(name);
|
||||
return new NoopSource();
|
||||
}
|
||||
});
|
||||
target.search(list("foo", "bar", "foobar"), null);
|
||||
}));
|
||||
target.search(searchForList("foo", "bar", "foobar"), null);
|
||||
Assert.assertEquals(hashset("foo", "bar", "foobar"), searched);
|
||||
}
|
||||
|
||||
private SourceProvider provider(String supports, BiFunction<String, SearchPath, ClassSource> fn) {
|
||||
return new SourceProvider() {
|
||||
@Override
|
||||
public ClassSource findSource(String name, SearchPath searchPath) {
|
||||
return fn.apply(name, searchPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(String type) {
|
||||
return supports.equals(type);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldSearchAllProviders() {
|
||||
public void itShouldOnlySearchSupportedProvidersForKnownType() {
|
||||
Set<String> visited = new HashSet<>();
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider((name, searchPath) -> {
|
||||
visited.add("1");
|
||||
|
||||
target.addProvider(provider("jar", (name, searchPath) -> {
|
||||
visited.add("jar");
|
||||
return null;
|
||||
});
|
||||
target.addProvider((name, searchPath) -> {
|
||||
visited.add("2");
|
||||
}));
|
||||
|
||||
target.addProvider(provider("dir", (name, searchPath) -> {
|
||||
visited.add("dir");
|
||||
return null;
|
||||
});
|
||||
}));
|
||||
|
||||
try {
|
||||
target.search(list("foo"), null);
|
||||
target.search(list(new SearchFor("some", "dir")), null);
|
||||
} catch (InternalError e) {
|
||||
// throws because no provider gives a source
|
||||
}
|
||||
|
||||
Assert.assertEquals(hashset("dir"), visited);
|
||||
}
|
||||
|
||||
@Test(expected = InternalError.class)
|
||||
public void itShouldThrowErrorIfMultipleSourcesAreAvailable() {
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(provider("", (name, searchPath) -> consumer -> Assert.fail()));
|
||||
target.addProvider(provider("", (name, searchPath) -> consumer -> Assert.fail()));
|
||||
|
||||
target.search(searchForList("somethign"), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldSearchAllProvidersForUnknownType() {
|
||||
Set<String> visited = new HashSet<>();
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(provider("", (name, searchPath) -> {
|
||||
visited.add("1");
|
||||
return null;
|
||||
}));
|
||||
target.addProvider(provider("", (name, searchPath) -> {
|
||||
visited.add("2");
|
||||
return null;
|
||||
}));
|
||||
|
||||
try {
|
||||
target.search(searchForList("foo"), null);
|
||||
} catch (InternalError e) {
|
||||
// throws because no provider gives a source
|
||||
}
|
||||
@ -84,6 +138,11 @@ public class ClassSearchTest {
|
||||
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(new SourceProvider() {
|
||||
@Override
|
||||
public boolean supports(String type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassSource findSource(String name, SearchPath searchPath) {
|
||||
return new ClassSource() {
|
||||
@ -101,7 +160,7 @@ public class ClassSearchTest {
|
||||
}
|
||||
});
|
||||
|
||||
java.util.List<LoadedClass> search = target.search(list("/tmp/something"), null);
|
||||
java.util.List<LoadedClass> search = target.search(searchForList("/tmp/something"), null);
|
||||
Assert.assertEquals(list(new LoadedClass("foo.Bar", null)), search);
|
||||
}
|
||||
|
||||
@ -115,8 +174,16 @@ public class ClassSearchTest {
|
||||
};
|
||||
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider((name, searchPath) -> consumer -> consumer.accept("foo.Bar", classLoader));
|
||||
target.search(list("foobar"), null);
|
||||
target.addProvider(provider("", (name, searchPath) -> consumer -> consumer.accept("foo.Bar", classLoader)));
|
||||
target.search(searchForList("foobar"), null);
|
||||
}
|
||||
|
||||
private List<SearchFor> searchForList(String... entries) {
|
||||
List<SearchFor> list = new ArrayList<>();
|
||||
for (String entry : entries) {
|
||||
list.add(new SearchFor(entry));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private <T> List<T> list(T... entries) {
|
||||
|
||||
@ -20,6 +20,14 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.ClassSourceTest
|
||||
*/
|
||||
|
||||
package jdk.tools.jaotc.test.collect;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
@ -27,6 +27,8 @@ import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.tools.jaotc.collect.FileSupport;
|
||||
|
||||
public class FakeFileSupport extends FileSupport {
|
||||
private final Set<String> exists = new HashSet<>();
|
||||
private final Set<String> directories = new HashSet<>();
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
*/
|
||||
package jdk.tools.jaotc.test.collect;
|
||||
|
||||
import jdk.tools.jaotc.collect.SearchPath;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@ -20,6 +20,17 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
*
|
||||
* @build jdk.tools.jaotc.test.collect.Utils
|
||||
* @build jdk.tools.jaotc.test.collect.FakeFileSupport
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.SearchPathTest
|
||||
*/
|
||||
|
||||
package jdk.tools.jaotc.test.collect;
|
||||
|
||||
import org.junit.Before;
|
||||
@ -30,6 +41,8 @@ import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import jdk.tools.jaotc.collect.*;
|
||||
|
||||
import static jdk.tools.jaotc.test.collect.Utils.set;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
@ -21,11 +21,22 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* jdk.aot/jdk.tools.jaotc.collect.directory
|
||||
* @compile ../Utils.java
|
||||
* @compile ../FakeFileSupport.java
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.directory.DirectorySourceProviderTest
|
||||
*/
|
||||
|
||||
package jdk.tools.jaotc.test.collect.directory;
|
||||
|
||||
import jdk.tools.jaotc.collect.ClassSource;
|
||||
import jdk.tools.jaotc.collect.directory.DirectorySourceProvider;
|
||||
import jdk.tools.jaotc.test.collect.FakeFileSupport;
|
||||
import jdk.tools.jaotc.test.collect.FileSupport;
|
||||
import jdk.tools.jaotc.collect.FileSupport;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
@ -20,9 +20,23 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* jdk.aot/jdk.tools.jaotc.collect.jar
|
||||
* @compile ../Utils.java
|
||||
* @compile ../FakeFileSupport.java
|
||||
* @compile ../FakeSearchPath.java
|
||||
*
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.jar.JarSourceProviderTest
|
||||
*/
|
||||
|
||||
package jdk.tools.jaotc.test.collect.jar;
|
||||
|
||||
import jdk.tools.jaotc.collect.ClassSource;
|
||||
import jdk.tools.jaotc.collect.jar.JarSourceProvider;
|
||||
import jdk.tools.jaotc.test.collect.FakeFileSupport;
|
||||
import jdk.tools.jaotc.test.collect.FakeSearchPath;
|
||||
import org.junit.Assert;
|
||||
|
||||
@ -20,15 +20,31 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* jdk.aot/jdk.tools.jaotc.collect.module
|
||||
* @compile ../Utils.java
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.module.ModuleSourceProviderTest
|
||||
*/
|
||||
|
||||
package jdk.tools.jaotc.test.collect.module;
|
||||
|
||||
import jdk.tools.jaotc.*;
|
||||
import jdk.tools.jaotc.test.collect.FakeSearchPath;
|
||||
import jdk.tools.jaotc.collect.FileSupport;
|
||||
import jdk.tools.jaotc.collect.module.ModuleSource;
|
||||
import jdk.tools.jaotc.collect.module.ModuleSourceProvider;
|
||||
import jdk.tools.jaotc.test.collect.Utils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
@ -36,28 +52,42 @@ import static org.junit.Assert.assertNull;
|
||||
public class ModuleSourceProviderTest {
|
||||
private ClassLoader classLoader;
|
||||
private ModuleSourceProvider target;
|
||||
private FileSupport fileSupport;
|
||||
private BiFunction<Path, Path, Path> getSubDirectory = null;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
classLoader = new FakeClassLoader();
|
||||
target = new ModuleSourceProvider(FileSystems.getDefault(), classLoader);
|
||||
fileSupport = new FileSupport() {
|
||||
|
||||
@Override
|
||||
public boolean isDirectory(Path path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getSubDirectory(FileSystem fileSystem, Path root, Path path) throws IOException {
|
||||
if (getSubDirectory == null) {
|
||||
throw new IOException("Nope");
|
||||
}
|
||||
return getSubDirectory.apply(root, path);
|
||||
}
|
||||
};
|
||||
target = new ModuleSourceProvider(FileSystems.getDefault(), classLoader, fileSupport);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldUseSearchPath() {
|
||||
FakeSearchPath searchPath = new FakeSearchPath("blah/java.base");
|
||||
ModuleSource source = (ModuleSource) target.findSource("java.base", searchPath);
|
||||
assertEquals(Utils.set("java.base"), searchPath.entries);
|
||||
assertEquals("blah/java.base", source.getModulePath().toString());
|
||||
assertEquals("module:blah/java.base", source.toString());
|
||||
}
|
||||
public void itShouldUseFileSupport() {
|
||||
getSubDirectory = (root, path) -> {
|
||||
if (root.toString().equals("modules") && path.toString().equals("test.module")) {
|
||||
return Paths.get("modules/test.module");
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullIfSearchPathReturnsNull() {
|
||||
FakeSearchPath searchPath = new FakeSearchPath(null);
|
||||
ModuleSource source = (ModuleSource) target.findSource("jdk.base", searchPath);
|
||||
assertEquals(Utils.set("jdk.base"), searchPath.entries);
|
||||
assertNull(source);
|
||||
ModuleSource source = (ModuleSource) target.findSource("test.module", null);
|
||||
assertEquals("modules/test.module", source.getModulePath().toString());
|
||||
assertEquals("module:modules/test.module", source.toString());
|
||||
}
|
||||
|
||||
private static class FakeClassLoader extends ClassLoader {
|
||||
|
||||
69
hotspot/test/compiler/c1/UnsafeVolatileGuardTest.java
Normal file
69
hotspot/test/compiler/c1/UnsafeVolatileGuardTest.java
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Red Hat Inc. 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.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8175887
|
||||
* @summary C1 value numbering handling of Unsafe.get*Volatile is incorrect
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:TieredStopAtLevel=1 UnsafeVolatileGuardTest
|
||||
*/
|
||||
public class UnsafeVolatileGuardTest {
|
||||
volatile static private int a;
|
||||
static private int b;
|
||||
|
||||
static final jdk.internal.misc.Unsafe UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
|
||||
|
||||
static final Object BASE;
|
||||
static final long OFFSET;
|
||||
|
||||
static {
|
||||
try {
|
||||
Field f = UnsafeVolatileGuardTest.class.getDeclaredField("a");
|
||||
BASE = UNSAFE.staticFieldBase(f);
|
||||
OFFSET = UNSAFE.staticFieldOffset(f);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void test() {
|
||||
int tt = b; // makes the JVM CSE the value of b
|
||||
|
||||
while (UNSAFE.getIntVolatile(BASE, OFFSET) == 0) {} // burn
|
||||
if (b == 0) {
|
||||
System.err.println("wrong value of b");
|
||||
System.exit(1); // fail hard to report the error
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String [] args) throws Exception {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
new Thread(UnsafeVolatileGuardTest::test).start();
|
||||
}
|
||||
b = 1;
|
||||
a = 1;
|
||||
}
|
||||
}
|
||||
52
hotspot/test/compiler/c1/VolatileGuardTest.java
Normal file
52
hotspot/test/compiler/c1/VolatileGuardTest.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Red Hat Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8175887
|
||||
* @summary C1 doesn't respect the JMM with volatile field loads
|
||||
*
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:TieredStopAtLevel=1 VolatileGuardTest
|
||||
*/
|
||||
public class VolatileGuardTest {
|
||||
volatile static private int a;
|
||||
static private int b;
|
||||
|
||||
static void test() {
|
||||
int tt = b; // makes the JVM CSE the value of b
|
||||
|
||||
while (a == 0) {} // burn
|
||||
if (b == 0) {
|
||||
System.err.println("wrong value of b");
|
||||
System.exit(1); // fail hard to report the error
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String [] args) throws Exception {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
new Thread(VolatileGuardTest::test).start();
|
||||
}
|
||||
b = 1;
|
||||
a = 1;
|
||||
}
|
||||
}
|
||||
@ -39,7 +39,7 @@ import jdk.test.lib.Asserts;
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @requires vm.flavor == "server" & !vm.emulatedClient
|
||||
* @requires vm.flavor == "server" & !vm.emulatedClient & !(vm.opt.TieredStopAtLevel == 1)
|
||||
* @build jdk.test.lib.apps.*
|
||||
* @run main/othervm TestPrintMdo
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user