7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
Summary: Write method signature handler under lock to prevent race with growable array resizing
Reviewed-by: dsamersoff, dholmes
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Feb 02 11:54:26 2011 -0500
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Feb 02 18:38:40 2011 -0500
@@ -1184,9 +1184,7 @@
handler_index = _fingerprints->length() - 1;
}
}
- } else {
- CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
- }
+ // Set handler under SignatureHandlerLibrary_lock
if (handler_index < 0) {
// use generic signature handler
method->set_signature_handler(Interpreter::slow_signature_handler());
@@ -1194,21 +1192,29 @@
// set handler
method->set_signature_handler(_handlers->at(handler_index));
}
+ } else {
+ CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
+ // use generic signature handler
+ method->set_signature_handler(Interpreter::slow_signature_handler());
+ }
}
#ifdef ASSERT
- int handler_index, fingerprint_index;
+ int handler_index = -1;
+ int fingerprint_index = -2;
{
// '_handlers' and '_fingerprints' are 'GrowableArray's and are NOT synchronized
// in any way if accessed from multiple threads. To avoid races with another
// thread which may change the arrays in the above, mutex protected block, we
// have to protect this read access here with the same mutex as well!
MutexLocker mu(SignatureHandlerLibrary_lock);
+ if (_handlers != NULL) {
handler_index = _handlers->find(method->signature_handler());
fingerprint_index = _fingerprints->find(Fingerprinter(method).fingerprint());
}
+ }
assert(method->signature_handler() == Interpreter::slow_signature_handler() ||
handler_index == fingerprint_index, "sanity check");
-#endif
+#endif // ASSERT
}