--- a/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp Fri Mar 03 20:50:26 2017 +0100
@@ -618,7 +618,7 @@
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 @@
// 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));
--- a/hotspot/src/jdk.aot/unix/native/libjelfshim/jdk_tools_jaotc_jnilibelf_JNILibELFAPI.c Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/jdk.aot/unix/native/libjelfshim/jdk_tools_jaotc_jnilibelf_JNILibELFAPI.c Fri Mar 03 20:50:26 2017 +0100
@@ -70,18 +70,17 @@
*/
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 @@
* 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;
}
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Fri Mar 03 20:50:26 2017 +0100
@@ -613,7 +613,7 @@
// 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 @@
LIR_OprDesc::cpu_register |
LIR_OprDesc::double_size);
}
-#endif // __SOFTFP__
+#endif // ARM32
#if defined(X86)
static LIR_Opr single_xmm(int reg) {
--- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp Fri Mar 03 20:50:26 2017 +0100
@@ -157,6 +157,12 @@
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 @@
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 */ };
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Fri Mar 03 20:50:26 2017 +0100
@@ -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 @@
_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 @@
_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 @@
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 @@
_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 @@
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 @@
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()));
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Fri Mar 03 20:50:26 2017 +0100
@@ -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 @@
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 @@
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 @@
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 @@
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);
--- a/hotspot/src/share/vm/classfile/moduleEntry.cpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp Fri Mar 03 20:50:26 2017 +0100
@@ -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 @@
// 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);
}
}
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Fri Mar 03 20:50:26 2017 +0100
@@ -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 @@
return NULL;
}
+
int CompilerToVM::Data::Klass_vtable_start_offset;
int CompilerToVM::Data::Klass_vtable_length_offset;
@@ -985,6 +1011,8 @@
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;
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp Fri Mar 03 20:50:26 2017 +0100
@@ -206,4 +206,14 @@
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
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Fri Mar 03 20:50:26 2017 +0100
@@ -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) \
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java Fri Mar 03 20:50:26 2017 +0100
@@ -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.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(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);
}
- });
- target.search(list("foo", "bar", "foobar"), null);
- Assert.assertEquals(hashset("foo", "bar", "foobar"), searched);
+
+ @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) -> {
+
+ target.addProvider(provider("jar", (name, searchPath) -> {
+ visited.add("jar");
+ return null;
+ }));
+
+ target.addProvider(provider("dir", (name, searchPath) -> {
+ visited.add("dir");
+ return null;
+ }));
+
+ try {
+ 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((name, searchPath) -> {
+ }));
+ target.addProvider(provider("", (name, searchPath) -> {
visited.add("2");
return null;
- });
+ }));
try {
- target.search(list("foo"), null);
+ target.search(searchForList("foo"), null);
} catch (InternalError e) {
// throws because no provider gives a source
}
@@ -85,6 +139,11 @@
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() {
@Override
@@ -101,7 +160,7 @@
}
});
- 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 @@
};
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) {
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java Fri Mar 03 20:50:26 2017 +0100
@@ -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;
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java Fri Mar 03 20:50:26 2017 +0100
@@ -27,6 +27,8 @@
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<>();
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java Fri Mar 03 20:50:26 2017 +0100
@@ -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;
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java Fri Mar 03 20:50:26 2017 +0100
@@ -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.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.*;
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java Fri Mar 03 20:50:26 2017 +0100
@@ -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;
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java Fri Mar 03 20:50:26 2017 +0100
@@ -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;
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java Fri Mar 03 20:50:26 2017 +0100
@@ -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 @@
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 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c1/UnsafeVolatileGuardTest.java Fri Mar 03 20:50:26 2017 +0100
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c1/VolatileGuardTest.java Fri Mar 03 20:50:26 2017 +0100
@@ -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;
+ }
+}
--- a/hotspot/test/serviceability/sa/TestPrintMdo.java Thu Mar 02 21:16:15 2017 +0000
+++ b/hotspot/test/serviceability/sa/TestPrintMdo.java Fri Mar 03 20:50:26 2017 +0100
@@ -39,7 +39,7 @@
/*
* @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
*/