Mercurial > hg > truffle
diff src/share/vm/oops/cpCacheOop.cpp @ 1903:87d6a4d1ecbc
6990192: VM crashes in ciTypeFlow::get_block_for()
Reviewed-by: never
author | twisti |
---|---|
date | Tue, 19 Oct 2010 02:52:57 -0700 |
parents | e0ba4e04c839 |
children | f95d63e2154a |
line wrap: on
line diff
--- a/src/share/vm/oops/cpCacheOop.cpp Mon Oct 18 01:54:24 2010 -0700 +++ b/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