# HG changeset patch # User lana # Date 1489101359 0 # Node ID 97757a2aa0f40ee5458db1dae7a30a044f09fe2d # Parent 56713dcfe871f0710db80764a6943bf7619428de# Parent 0e5d20d3be1dc71ee3e7afce92f897d2a2d44a39 Merge diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/make/test/JtregNative.gmk diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp --- a/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp Thu Mar 09 23:15:59 2017 +0000 @@ -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)); diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/arm/vm/interp_masm_arm.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/arm/vm/interp_masm_arm.hpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/arm/vm/jniFastGetField_arm.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/arm/vm/templateInterpreterGenerator_arm.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/ppc/vm/frame_ppc.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/sparc/vm/jniFastGetField_sparc.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/jdk.aot/unix/native/libjelfshim/jdk_tools_jaotc_jnilibelf_JNILibELFAPI.c --- a/hotspot/src/jdk.aot/unix/native/libjelfshim/jdk_tools_jaotc_jnilibelf_JNILibELFAPI.c Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/jdk.aot/unix/native/libjelfshim/jdk_tools_jaotc_jnilibelf_JNILibELFAPI.c Thu Mar 09 23:15:59 2017 +0000 @@ -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, "", "(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, "", "(J)V"); + if (constructorId != NULL) { + retObj = (*env)->NewObject(env, ptrClass, constructorId, nativeAddr); + } + } return retObj; } diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/c1/c1_LIR.hpp --- a/hotspot/src/share/vm/c1/c1_LIR.hpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Thu Mar 09 23:15:59 2017 +0000 @@ -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) { diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/c1/c1_ValueMap.hpp --- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp Thu Mar 09 23:15:59 2017 +0000 @@ -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 */ }; diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/classfile/classLoaderData.cpp --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Mar 09 23:15:59 2017 +0000 @@ -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())); diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/classfile/classLoaderData.hpp --- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Thu Mar 09 23:15:59 2017 +0000 @@ -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 { + 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); diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/classfile/moduleEntry.cpp --- a/hotspot/src/share/vm/classfile/moduleEntry.cpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp Thu Mar 09 23:15:59 2017 +0000 @@ -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); } } diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Mar 09 23:15:59 2017 +0000 @@ -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; diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp Thu Mar 09 23:15:59 2017 +0000 @@ -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 diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp --- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Thu Mar 09 23:15:59 2017 +0000 @@ -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) \ diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/prims/jni.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/prims/jvmtiEnv.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/runtime/javaCalls.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/runtime/javaCalls.hpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/runtime/jniHandles.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/runtime/jniHandles.hpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/src/share/vm/shark/sharkNativeWrapper.cpp diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java --- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java Thu Mar 09 23:15:59 2017 +0000 @@ -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 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 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 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 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 search = target.search(list("/tmp/something"), null); + java.util.List 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 searchForList(String... entries) { + List list = new ArrayList<>(); + for (String entry : entries) { + list.add(new SearchFor(entry)); + } + return list; } private List list(T... entries) { diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java --- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java Thu Mar 09 23:15:59 2017 +0000 @@ -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; diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java --- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java Thu Mar 09 23:15:59 2017 +0000 @@ -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 exists = new HashSet<>(); private final Set directories = new HashSet<>(); diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java --- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java Thu Mar 09 23:15:59 2017 +0000 @@ -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; diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java --- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java Thu Mar 09 23:15:59 2017 +0000 @@ -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.*; diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java --- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java Thu Mar 09 23:15:59 2017 +0000 @@ -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; diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java --- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java Thu Mar 09 23:15:59 2017 +0000 @@ -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; diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java --- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java Thu Mar 09 23:15:59 2017 +0000 @@ -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 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 { diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/c1/UnsafeVolatileGuardTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/c1/UnsafeVolatileGuardTest.java Thu Mar 09 23:15:59 2017 +0000 @@ -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; + } +} diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/compiler/c1/VolatileGuardTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/c1/VolatileGuardTest.java Thu Mar 09 23:15:59 2017 +0000 @@ -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; + } +} diff -r 56713dcfe871 -r 97757a2aa0f4 hotspot/test/serviceability/sa/TestPrintMdo.java --- a/hotspot/test/serviceability/sa/TestPrintMdo.java Thu Mar 09 21:35:17 2017 +0000 +++ b/hotspot/test/serviceability/sa/TestPrintMdo.java Thu Mar 09 23:15:59 2017 +0000 @@ -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 */