# HG changeset patch # User poonam # Date 1434546595 0 # Node ID 9d514a2d02ff8d8d69b663fa874a6da482772f3e # Parent 68de83e1d912914686d832b069b69141a68fef31# Parent 49499180315f6787ded6d278dbe9607dfc8928db Merge diff -r 68de83e1d912 -r 9d514a2d02ff .hgtags --- a/.hgtags Wed Jun 17 05:56:43 2015 -0700 +++ b/.hgtags Wed Jun 17 13:09:55 2015 +0000 @@ -648,3 +648,5 @@ 624f4cc05e7e95dd2103f343c54d7bdea6a81919 hs25.60-b18 3fa5c654c143fe309e5ddda92adc5fb132365bcf jdk8u60-b18 b852350a2bc6d5f43006e2be53fb74d148290708 hs25.60-b19 +bd9221771f6e34e63b3b340ffcf9906ccf882dae jdk8u60-b19 +e01a710549a962cee94728271248a7d89fb56c49 hs25.60-b20 diff -r 68de83e1d912 -r 9d514a2d02ff make/hotspot_version --- a/make/hotspot_version Wed Jun 17 05:56:43 2015 -0700 +++ b/make/hotspot_version Wed Jun 17 13:09:55 2015 +0000 @@ -35,7 +35,7 @@ HS_MAJOR_VER=25 HS_MINOR_VER=60 -HS_BUILD_NUMBER=20 +HS_BUILD_NUMBER=21 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff -r 68de83e1d912 -r 9d514a2d02ff make/linux/Makefile --- a/make/linux/Makefile Wed Jun 17 05:56:43 2015 -0700 +++ b/make/linux/Makefile Wed Jun 17 13:09:55 2015 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2015, 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 @@ -229,7 +229,7 @@ # Solaris 2.5.1, 2.6). # Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok. -SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3% +SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3% 4% OS_VERSION := $(shell uname -r) EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION)) diff -r 68de83e1d912 -r 9d514a2d02ff src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Wed Jun 17 05:56:43 2015 -0700 +++ b/src/share/vm/interpreter/linkResolver.cpp Wed Jun 17 13:09:55 2015 +0000 @@ -1592,6 +1592,26 @@ result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); } +static void wrap_invokedynamic_exception(TRAPS) { + if (HAS_PENDING_EXCEPTION) { + if (TraceMethodHandles) { + tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION)); + PENDING_EXCEPTION->print(); + } + if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { + // throw these guys, since they are already wrapped + return; + } + if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { + // intercept only LinkageErrors which might have failed to wrap + return; + } + // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS. + Handle nested_exception(THREAD, PENDING_EXCEPTION); + CLEAR_PENDING_EXCEPTION; + THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception) + } +} void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { assert(EnableInvokeDynamic, ""); @@ -1607,7 +1627,8 @@ ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index); if (cpce->is_f1_null()) { int pool_index = cpce->constant_pool_index(); - oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, CHECK); + oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, THREAD); + wrap_invokedynamic_exception(CHECK); assert(bsm_info != NULL, ""); // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic. bootstrap_specifier = Handle(THREAD, bsm_info); @@ -1616,7 +1637,8 @@ methodHandle method( THREAD, cpce->f1_as_method()); Handle appendix( THREAD, cpce->appendix_if_resolved(pool)); Handle method_type(THREAD, cpce->method_type_if_resolved(pool)); - result.set_handle(method, appendix, method_type, CHECK); + result.set_handle(method, appendix, method_type, THREAD); + wrap_invokedynamic_exception(CHECK); return; } @@ -1647,25 +1669,9 @@ &resolved_appendix, &resolved_method_type, THREAD); - if (HAS_PENDING_EXCEPTION) { - if (TraceMethodHandles) { - tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION)); - PENDING_EXCEPTION->print(); - } - if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { - // throw these guys, since they are already wrapped - return; - } - if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { - // intercept only LinkageErrors which might have failed to wrap - return; - } - // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS. - Handle nested_exception(THREAD, PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; - THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception) - } - result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); + wrap_invokedynamic_exception(CHECK); + result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD); + wrap_invokedynamic_exception(CHECK); } //------------------------------------------------------------------------------------------------------------------------ diff -r 68de83e1d912 -r 9d514a2d02ff src/share/vm/memory/heap.cpp --- a/src/share/vm/memory/heap.cpp Wed Jun 17 05:56:43 2015 -0700 +++ b/src/share/vm/memory/heap.cpp Wed Jun 17 13:09:55 2015 +0000 @@ -99,9 +99,7 @@ // Reserve and initialize space for _memory. size_t page_size = os::vm_page_size(); if (os::can_execute_large_page_memory()) { - const size_t min_pages = 8; - page_size = MIN2(os::page_size_for_region_aligned(committed_size, min_pages), - os::page_size_for_region_aligned(reserved_size, min_pages)); + page_size = os::page_size_for_region_unaligned(reserved_size, 8); } const size_t granularity = os::vm_allocation_granularity(); diff -r 68de83e1d912 -r 9d514a2d02ff src/share/vm/memory/metaspace.cpp --- a/src/share/vm/memory/metaspace.cpp Wed Jun 17 05:56:43 2015 -0700 +++ b/src/share/vm/memory/metaspace.cpp Wed Jun 17 13:09:55 2015 +0000 @@ -622,7 +622,8 @@ Metachunk* _chunks_in_use[NumberOfInUseLists]; Metachunk* _current_chunk; - // Maximum number of small chunks to allocate to a SpaceManager + // Number of small chunks to allocate to a manager + // If class space manager, small chunks are unlimited static uint const _small_chunk_limit; // Sum of all space in allocated chunks @@ -736,8 +737,6 @@ // Block allocation and deallocation. // Allocates a block from the current chunk MetaWord* allocate(size_t word_size); - // Allocates a block from a small chunk - MetaWord* get_small_chunk_and_allocate(size_t word_size); // Helper for allocations MetaWord* allocate_work(size_t word_size); @@ -2032,8 +2031,9 @@ size_t SpaceManager::calc_chunk_size(size_t word_size) { // Decide between a small chunk and a medium chunk. Up to - // _small_chunk_limit small chunks can be allocated. - // After that a medium chunk is preferred. + // _small_chunk_limit small chunks can be allocated but + // once a medium chunk has been allocated, no more small + // chunks will be allocated. size_t chunk_word_size; if (chunks_in_use(MediumIndex) == NULL && sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) { @@ -2101,7 +2101,7 @@ word_size, words_used, words_left); } - // Get another chunk + // Get another chunk out of the virtual space size_t grow_chunks_by_words = calc_chunk_size(word_size); Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); @@ -2432,43 +2432,6 @@ return next; } -/* - * The policy is to allocate up to _small_chunk_limit small chunks - * after which only medium chunks are allocated. This is done to - * reduce fragmentation. In some cases, this can result in a lot - * of small chunks being allocated to the point where it's not - * possible to expand. If this happens, there may be no medium chunks - * available and OOME would be thrown. Instead of doing that, - * if the allocation request size fits in a small chunk, an attempt - * will be made to allocate a small chunk. - */ -MetaWord* SpaceManager::get_small_chunk_and_allocate(size_t word_size) { - if (word_size + Metachunk::overhead() > small_chunk_size()) { - return NULL; - } - - MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); - MutexLockerEx cl1(expand_lock(), Mutex::_no_safepoint_check_flag); - - Metachunk* chunk = chunk_manager()->chunk_freelist_allocate(small_chunk_size()); - - MetaWord* mem = NULL; - - if (chunk != NULL) { - // Add chunk to the in-use chunk list and do an allocation from it. - // Add to this manager's list of chunks in use. - add_chunk(chunk, false); - mem = chunk->allocate(word_size); - - inc_used_metrics(word_size); - - // Track metaspace memory usage statistic. - track_metaspace_memory_usage(); - } - - return mem; -} - MetaWord* SpaceManager::allocate(size_t word_size) { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); @@ -3548,18 +3511,7 @@ } if (result == NULL) { - SpaceManager* sm; - if (is_class_space_allocation(mdtype)) { - sm = loader_data->metaspace_non_null()->class_vsm(); - } else { - sm = loader_data->metaspace_non_null()->vsm(); - } - - result = sm->get_small_chunk_and_allocate(word_size); - - if (result == NULL) { - report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL); - } + report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL); } // Zero initialize. diff -r 68de83e1d912 -r 9d514a2d02ff src/share/vm/opto/loopTransform.cpp --- a/src/share/vm/opto/loopTransform.cpp Wed Jun 17 05:56:43 2015 -0700 +++ b/src/share/vm/opto/loopTransform.cpp Wed Jun 17 13:09:55 2015 +0000 @@ -1821,7 +1821,10 @@ // Find the pre-loop limit; we will expand it's iterations to // not ever trip low tests. Node *p_f = iffm->in(0); - assert(p_f->Opcode() == Op_IfFalse, ""); + // pre loop may have been optimized out + if (p_f->Opcode() != Op_IfFalse) { + return; + } CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd(); assert(pre_end->loopnode()->is_pre_loop(), ""); Node *pre_opaq1 = pre_end->limit(); diff -r 68de83e1d912 -r 9d514a2d02ff src/share/vm/opto/type.cpp --- a/src/share/vm/opto/type.cpp Wed Jun 17 05:56:43 2015 -0700 +++ b/src/share/vm/opto/type.cpp Wed Jun 17 13:09:55 2015 +0000 @@ -1180,11 +1180,11 @@ // Certain normalizations keep us sane when comparing types. // The 'SMALLINT' covers constants and also CC and its relatives. if (lo <= hi) { - if ((juint)(hi - lo) <= SMALLINT) w = Type::WidenMin; - if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; // TypeInt::INT + if (((juint)hi - lo) <= SMALLINT) w = Type::WidenMin; + if (((juint)hi - lo) >= max_juint) w = Type::WidenMax; // TypeInt::INT } else { - if ((juint)(lo - hi) <= SMALLINT) w = Type::WidenMin; - if ((juint)(lo - hi) >= max_juint) w = Type::WidenMin; // dual TypeInt::INT + if (((juint)lo - hi) <= SMALLINT) w = Type::WidenMin; + if (((juint)lo - hi) >= max_juint) w = Type::WidenMin; // dual TypeInt::INT } return w; } @@ -1438,11 +1438,11 @@ // Certain normalizations keep us sane when comparing types. // The 'SMALLINT' covers constants. if (lo <= hi) { - if ((julong)(hi - lo) <= SMALLINT) w = Type::WidenMin; - if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; // TypeLong::LONG + if (((julong)hi - lo) <= SMALLINT) w = Type::WidenMin; + if (((julong)hi - lo) >= max_julong) w = Type::WidenMax; // TypeLong::LONG } else { - if ((julong)(lo - hi) <= SMALLINT) w = Type::WidenMin; - if ((julong)(lo - hi) >= max_julong) w = Type::WidenMin; // dual TypeLong::LONG + if (((julong)lo - hi) <= SMALLINT) w = Type::WidenMin; + if (((julong)lo - hi) >= max_julong) w = Type::WidenMin; // dual TypeLong::LONG } return w; } diff -r 68de83e1d912 -r 9d514a2d02ff src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Wed Jun 17 05:56:43 2015 -0700 +++ b/src/share/vm/prims/jni.cpp Wed Jun 17 13:09:55 2015 +0000 @@ -1325,39 +1325,32 @@ Method* m = Method::resolve_jmethod_id(method_id); number_of_parameters = m->size_of_parameters(); Klass* holder = m->method_holder(); - if (!(holder)->is_interface()) { + if (call_type != JNI_VIRTUAL) { + selected_method = m; + } else if (!m->has_itable_index()) { // non-interface call -- for that little speed boost, don't handlize debug_only(No_Safepoint_Verifier nosafepoint;) - if (call_type == JNI_VIRTUAL) { - // jni_GetMethodID makes sure class is linked and initialized - // so m should have a valid vtable index. - assert(!m->has_itable_index(), ""); - int vtbl_index = m->vtable_index(); - if (vtbl_index != Method::nonvirtual_vtable_index) { - Klass* k = h_recv->klass(); - // k might be an arrayKlassOop but all vtables start at - // the same place. The cast is to avoid virtual call and assertion. - InstanceKlass *ik = (InstanceKlass*)k; - selected_method = ik->method_at_vtable(vtbl_index); - } else { - // final method - selected_method = m; - } + // jni_GetMethodID makes sure class is linked and initialized + // so m should have a valid vtable index. + assert(m->valid_vtable_index(), "no valid vtable index"); + int vtbl_index = m->vtable_index(); + if (vtbl_index != Method::nonvirtual_vtable_index) { + Klass* k = h_recv->klass(); + // k might be an arrayKlassOop but all vtables start at + // the same place. The cast is to avoid virtual call and assertion. + InstanceKlass *ik = (InstanceKlass*)k; + selected_method = ik->method_at_vtable(vtbl_index); } else { - // JNI_NONVIRTUAL call + // final method selected_method = m; } } else { // interface call KlassHandle h_holder(THREAD, holder); - if (call_type == JNI_VIRTUAL) { - int itbl_index = m->itable_index(); - Klass* k = h_recv->klass(); - selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK); - } else { - selected_method = m; - } + int itbl_index = m->itable_index(); + Klass* k = h_recv->klass(); + selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK); } } diff -r 68de83e1d912 -r 9d514a2d02ff src/share/vm/runtime/interfaceSupport.cpp --- a/src/share/vm/runtime/interfaceSupport.cpp Wed Jun 17 05:56:43 2015 -0700 +++ b/src/share/vm/runtime/interfaceSupport.cpp Wed Jun 17 13:09:55 2015 +0000 @@ -185,19 +185,22 @@ # endif - +// invocation counter for InterfaceSupport::deoptimizeAll/zombieAll functions int deoptimizeAllCounter = 0; int zombieAllCounter = 0; - void InterfaceSupport::zombieAll() { - if (is_init_completed() && zombieAllCounter > ZombieALotInterval) { + // This method is called by all threads when a thread make + // transition to VM state (for example, runtime calls). + // Divide number of calls by number of threads to avoid + // dependence of ZombieAll events frequency on number of threads. + int value = zombieAllCounter / Threads::number_of_threads(); + if (is_init_completed() && value > ZombieALotInterval) { zombieAllCounter = 0; VM_ZombieAll op; VMThread::execute(&op); - } else { - zombieAllCounter++; } + zombieAllCounter++; } void InterfaceSupport::unlinkSymbols() { @@ -206,12 +209,17 @@ } void InterfaceSupport::deoptimizeAll() { - if (is_init_completed() ) { - if (DeoptimizeALot && deoptimizeAllCounter > DeoptimizeALotInterval) { + // This method is called by all threads when a thread make + // transition to VM state (for example, runtime calls). + // Divide number of calls by number of threads to avoid + // dependence of DeoptimizeAll events frequency on number of threads. + int value = deoptimizeAllCounter / Threads::number_of_threads(); + if (is_init_completed()) { + if (DeoptimizeALot && value > DeoptimizeALotInterval) { deoptimizeAllCounter = 0; VM_DeoptimizeAll op; VMThread::execute(&op); - } else if (DeoptimizeRandom && (deoptimizeAllCounter & 0x1f) == (os::random() & 0x1f)) { + } else if (DeoptimizeRandom && (value & 0x1F) == (os::random() & 0x1F)) { VM_DeoptimizeAll op; VMThread::execute(&op); } diff -r 68de83e1d912 -r 9d514a2d02ff test/runtime/invokedynamic/BootstrapMethodErrorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/invokedynamic/BootstrapMethodErrorTest.java Wed Jun 17 13:09:55 2015 +0000 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8051045 + * @summary Test that exceptions from invokedynamic are wrapped in BootstrapMethodError + * @modules java.base/jdk.internal.org.objectweb.asm + * @run main BootstrapMethodErrorTest + */ + +import java.lang.reflect.Method; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.Handle; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; + +public class BootstrapMethodErrorTest extends ClassLoader implements Opcodes { + + @Override + public Class findClass(String name) throws ClassNotFoundException { + byte[] b; + try { + b = loadClassData(name); + } catch (Throwable th) { + throw new ClassNotFoundException("Loading error", th); + } + return defineClass(name, b, 0, b.length); + } + + private byte[] loadClassData(String name) throws Exception { + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; + + if (name.equals("C")) { + cw.visit(52, ACC_SUPER | ACC_PUBLIC, "C", null, "java/lang/Object", null); + { + mv = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "m", "()V", null, null); + mv.visitCode(); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 1); + mv.visitEnd(); + } + cw.visitEnd(); + return cw.toByteArray(); + } else if (name.equals("Exec")) { + cw.visit(52, ACC_SUPER | ACC_PUBLIC, "Exec", null, "java/lang/Object", null); + { + mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "invokeRef", "()V", null, null); + mv.visitCode(); + Handle h = new Handle(H_INVOKESTATIC, "C", "m", "()V"); + mv.visitInvokeDynamicInsn("C", "()V", h); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + cw.visitEnd(); + return cw.toByteArray(); + } + return null; + } + + public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, NoSuchMethodException { + new BootstrapMethodErrorTest().test(); + } + + public void test() throws ClassNotFoundException, IllegalAccessException, NoSuchMethodException { + Class.forName("C", true, this); + Class exec = Class.forName("Exec", true, this); + + try { + exec.getMethod("invokeRef").invoke(null); + } catch (Throwable e) { + Throwable c = e.getCause(); + if (c == null) { + throw new RuntimeException( + "Expected BootstrapMethodError wrapped in an InvocationTargetException but it wasn't wrapped", e); + } else if (c instanceof BootstrapMethodError) { + // Only way to pass test, all else should throw + return; + } else { + throw new RuntimeException( + "Expected BootstrapMethodError but got another Error: " + + c.getClass().getName(), + c); + } + } + throw new RuntimeException("Expected BootstrapMethodError but no Error at all was thrown"); + } +} diff -r 68de83e1d912 -r 9d514a2d02ff test/test_env.sh --- a/test/test_env.sh Wed Jun 17 05:56:43 2015 -0700 +++ b/test/test_env.sh Wed Jun 17 13:09:55 2015 +0000 @@ -191,6 +191,11 @@ then VM_CPU="ia64" fi +grep "aarch64" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="aarch64" +fi export VM_TYPE VM_BITS VM_OS VM_CPU echo "VM_TYPE=${VM_TYPE}" echo "VM_BITS=${VM_BITS}"