8141585: CompilerDirectivesDCMDTest intermittently SEGVs in MethodMatcher::matcher
Summary: Missing methodHandle and read before lock
Reviewed-by: twisti
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Nov 05 12:37:03 2015 +0100
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Nov 13 10:08:44 2015 +0100
@@ -1676,13 +1676,7 @@
bool should_break = false;
int task_level = task->comp_level();
- // Look up matching directives
- DirectiveSet* directive = DirectivesStack::getMatchingDirective(task->method(), compiler(task_level));
-
- should_break = directive->BreakAtExecuteOption || task->check_break_at_flags();
- if (should_log && !directive->LogOption) {
- should_log = false;
- }
+ DirectiveSet* directive;
{
// create the handle inside it's own block so it can't
// accidentally be referenced once the thread transitions to
@@ -1691,12 +1685,20 @@
methodHandle method(thread, task->method());
assert(!method->is_native(), "no longer compile natives");
+ // Look up matching directives
+ directive = DirectivesStack::getMatchingDirective(method, compiler(task_level));
+
// Save information about this method in case of failure.
set_last_compile(thread, method, is_osr, task_level);
DTRACE_METHOD_COMPILE_BEGIN_PROBE(method, compiler_name(task_level));
}
+ should_break = directive->BreakAtExecuteOption || task->check_break_at_flags();
+ if (should_log && !directive->LogOption) {
+ should_log = false;
+ }
+
// Allocate a new set of JNI handles.
push_jni_handle_block();
Method* target_handle = task->method();
--- a/hotspot/src/share/vm/compiler/compilerDirectives.cpp Thu Nov 05 12:37:03 2015 +0100
+++ b/hotspot/src/share/vm/compiler/compilerDirectives.cpp Fri Nov 13 10:08:44 2015 +0100
@@ -527,12 +527,14 @@
DirectiveSet* DirectivesStack::getMatchingDirective(methodHandle method, AbstractCompiler *comp) {
assert(_depth > 0, "Must never be empty");
- CompilerDirectives* dir = _top;
- assert(dir != NULL, "Must be initialized");
DirectiveSet* match = NULL;
{
MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
+
+ CompilerDirectives* dir = _top;
+ assert(dir != NULL, "Must be initialized");
+
while (dir != NULL) {
if (dir->is_default_directive() || dir->match(method)) {
match = dir->get_for(comp);