# HG changeset patch # User twisti # Date 1287481977 25200 # Node ID 0c8b519af363930527d98e7a3c19834f88819e82 # Parent a20be5bfcbee9223b474e5b6eaff72a041e1b83c 6990192: VM crashes in ciTypeFlow::get_block_for() Reviewed-by: never diff -r a20be5bfcbee -r 0c8b519af363 hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Mon Oct 18 01:54:24 2010 -0700 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Oct 19 02:52:57 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, 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 @@ -26,12 +26,12 @@ # include "incls/_systemDictionary.cpp.incl" -Dictionary* SystemDictionary::_dictionary = NULL; -PlaceholderTable* SystemDictionary::_placeholders = NULL; -Dictionary* SystemDictionary::_shared_dictionary = NULL; -LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL; -ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL; -SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL; +Dictionary* SystemDictionary::_dictionary = NULL; +PlaceholderTable* SystemDictionary::_placeholders = NULL; +Dictionary* SystemDictionary::_shared_dictionary = NULL; +LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL; +ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL; +SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL; int SystemDictionary::_number_of_modifications = 0; @@ -1727,8 +1727,7 @@ placeholders_do(blk); // Visit extra methods - if (invoke_method_table() != NULL) - invoke_method_table()->oops_do(blk); + invoke_method_table()->oops_do(blk); // Loader constraints. We must keep the symbolOop used in the name alive. constraints()->always_strong_classes_do(blk); @@ -1766,8 +1765,7 @@ dictionary()->oops_do(f); // Visit extra methods - if (invoke_method_table() != NULL) - invoke_method_table()->oops_do(f); + invoke_method_table()->oops_do(f); // Partially loaded classes placeholders()->oops_do(f); @@ -1841,8 +1839,7 @@ void SystemDictionary::methods_do(void f(methodOop)) { dictionary()->methods_do(f); - if (invoke_method_table() != NULL) - invoke_method_table()->methods_do(f); + invoke_method_table()->methods_do(f); } // ---------------------------------------------------------------------------- @@ -1870,12 +1867,12 @@ // Allocate arrays assert(dictionary() == NULL, "SystemDictionary should only be initialized once"); - _dictionary = new Dictionary(_nof_buckets); - _placeholders = new PlaceholderTable(_nof_buckets); + _dictionary = new Dictionary(_nof_buckets); + _placeholders = new PlaceholderTable(_nof_buckets); _number_of_modifications = 0; - _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); - _resolution_errors = new ResolutionErrorTable(_resolution_error_size); - // _invoke_method_table is allocated lazily in find_method_handle_invoke() + _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); + _resolution_errors = new ResolutionErrorTable(_resolution_error_size); + _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); // Allocate private object used as system class loader lock _system_loader_lock_obj = oopFactory::new_system_objArray(0, CHECK); @@ -2346,10 +2343,6 @@ KlassHandle accessing_klass, TRAPS) { if (!EnableMethodHandles) return NULL; - if (invoke_method_table() == NULL) { - // create this side table lazily - _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); - } vmSymbols::SID name_id = vmSymbols::find_sid(name()); assert(name_id != vmSymbols::NO_SID, "must be a known name"); unsigned int hash = invoke_method_table()->compute_hash(signature, name_id); diff -r a20be5bfcbee -r 0c8b519af363 hotspot/src/share/vm/interpreter/interpreterRuntime.cpp --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Mon Oct 18 01:54:24 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Tue Oct 19 02:52:57 2010 -0700 @@ -720,8 +720,8 @@ // first resolve the signature to a MH.invoke methodOop if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) { JvmtiHideSingleStepping jhss(thread); - CallInfo info; - LinkResolver::resolve_invoke(info, Handle(), pool, + CallInfo callinfo; + LinkResolver::resolve_invoke(callinfo, Handle(), pool, site_index, bytecode, CHECK); // The main entry corresponds to a JVM_CONSTANT_InvokeDynamic, and serves // as a common reference point for all invokedynamic call sites with @@ -729,8 +729,8 @@ // as if it were an invokevirtual of MethodHandle.invoke. pool->cache()->entry_at(main_index)->set_method( bytecode, - info.resolved_method(), - info.vtable_index()); + callinfo.resolved_method(), + callinfo.vtable_index()); } // The method (f2 entry) of the main entry is the MH.invoke for the diff -r a20be5bfcbee -r 0c8b519af363 hotspot/src/share/vm/oops/cpCacheOop.cpp --- a/hotspot/src/share/vm/oops/cpCacheOop.cpp Mon Oct 18 01:54:24 2010 -0700 +++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp Tue Oct 19 02:52:57 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, 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,6 +87,19 @@ OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << 24)); } +// Atomically sets f1 if it is still NULL, otherwise it keeps the +// current value. +void ConstantPoolCacheEntry::set_f1_if_null_atomic(oop f1) { + // Use barriers as in oop_store + HeapWord* f1_addr = (HeapWord*) &_f1; + update_barrier_set_pre(f1_addr, f1); + void* result = Atomic::cmpxchg_ptr(f1, f1_addr, NULL); + bool success = (result == NULL); + if (success) { + update_barrier_set((void*) f1_addr, f1); + } + } + #ifdef ASSERT // It is possible to have two different dummy methodOops created // when the resolve code for invoke interface executes concurrently @@ -165,7 +178,12 @@ } assert(method->can_be_statically_bound(), "must be a MH invoker method"); assert(AllowTransitionalJSR292 || _f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized"); - set_f1(method()); + // SystemDictionary::find_method_handle_invoke only caches + // methods which signature classes are on the boot classpath, + // otherwise the newly created method is returned. To avoid + // races in that case we store the first one coming in into the + // cp-cache atomically if it's still unset. + set_f1_if_null_atomic(method()); needs_vfinal_flag = false; // _f2 is not an oop assert(!is_vfinal(), "f2 not an oop"); byte_no = 1; // coordinate this with bytecode_number & is_resolved diff -r a20be5bfcbee -r 0c8b519af363 hotspot/src/share/vm/oops/cpCacheOop.hpp --- a/hotspot/src/share/vm/oops/cpCacheOop.hpp Mon Oct 18 01:54:24 2010 -0700 +++ b/hotspot/src/share/vm/oops/cpCacheOop.hpp Tue Oct 19 02:52:57 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, 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 @@ -130,6 +130,7 @@ assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change"); oop_store(&_f1, f1); } + void set_f1_if_null_atomic(oop f1); void set_f2(intx f2) { assert(_f2 == 0 || _f2 == f2, "illegal field change"); _f2 = f2; } int as_flags(TosState state, bool is_final, bool is_vfinal, bool is_volatile, bool is_method_interface, bool is_method); diff -r a20be5bfcbee -r 0c8b519af363 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Mon Oct 18 01:54:24 2010 -0700 +++ b/hotspot/src/share/vm/runtime/thread.cpp Tue Oct 19 02:52:57 2010 -0700 @@ -1199,6 +1199,7 @@ _exception_pc = 0; _exception_handler_pc = 0; _exception_stack_size = 0; + _is_method_handle_return = 0; _jvmti_thread_state= NULL; _should_post_on_exceptions_flag = JNI_FALSE; _jvmti_get_loaded_classes_closure = NULL;