4930919: race condition in MDO creation at back branch locations
Summary: Reuse set_method_data_for_bcp() to setup mdp after MDO creation.
Reviewed-by: kvn, never
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -1295,16 +1295,13 @@
// Get the method data pointer from the methodOop and set the
// specified register to its value.
-void InterpreterMacroAssembler::set_method_data_pointer_offset(Register Roff) {
+void InterpreterMacroAssembler::set_method_data_pointer() {
assert(ProfileInterpreter, "must be profiling interpreter");
Label get_continue;
ld_ptr(Lmethod, in_bytes(methodOopDesc::method_data_offset()), ImethodDataPtr);
test_method_data_pointer(get_continue);
add(ImethodDataPtr, in_bytes(methodDataOopDesc::data_offset()), ImethodDataPtr);
- if (Roff != noreg)
- // Roff contains a method data index ("mdi"). It defaults to zero.
- add(ImethodDataPtr, Roff, ImethodDataPtr);
bind(get_continue);
}
@@ -1315,10 +1312,11 @@
Label zero_continue;
// Test MDO to avoid the call if it is NULL.
- ld_ptr(Lmethod, methodOopDesc::method_data_offset(), ImethodDataPtr);
+ ld_ptr(Lmethod, in_bytes(methodOopDesc::method_data_offset()), ImethodDataPtr);
test_method_data_pointer(zero_continue);
call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), Lmethod, Lbcp);
- set_method_data_pointer_offset(O0);
+ add(ImethodDataPtr, in_bytes(methodDataOopDesc::data_offset()), ImethodDataPtr);
+ add(ImethodDataPtr, O0, ImethodDataPtr);
bind(zero_continue);
}
@@ -1369,7 +1367,6 @@
}
void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocation_count,
- Register cur_bcp,
Register Rtmp,
Label &profile_continue) {
assert(ProfileInterpreter, "must be profiling interpreter");
@@ -1400,8 +1397,8 @@
delayed()->nop();
// Build it now.
- call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), cur_bcp);
- set_method_data_pointer_offset(O0);
+ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
+ set_method_data_pointer_for_bcp();
ba(false, profile_continue);
delayed()->nop();
bind(done);
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -269,12 +269,11 @@
#ifndef CC_INTERP
// Interpreter profiling operations
- void set_method_data_pointer() { set_method_data_pointer_offset(noreg); }
+ void set_method_data_pointer();
void set_method_data_pointer_for_bcp();
- void set_method_data_pointer_offset(Register mdi_reg);
void test_method_data_pointer(Label& zero_continue);
void verify_method_data_pointer();
- void test_invocation_counter_for_mdp(Register invocation_count, Register cur_bcp, Register Rtmp, Label &profile_continue);
+ void test_invocation_counter_for_mdp(Register invocation_count, Register Rtmp, Label &profile_continue);
void set_mdp_data_at(int constant, Register value);
void increment_mdp_data_at(Address counter, Register bumped_count,
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -1364,15 +1364,8 @@
// We have decided to profile this method in the interpreter
__ bind(profile_method);
- __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), Lbcp, true);
-
-#ifdef ASSERT
- __ tst(O0);
- __ breakpoint_trap(Assembler::notEqual);
-#endif
-
- __ set_method_data_pointer();
-
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
+ __ set_method_data_pointer_for_bcp();
__ ba(false, profile_method_continue);
__ delayed()->nop();
}
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -1689,7 +1689,7 @@
const Register G4_invoke_ctr = G4;
__ increment_backedge_counter(G4_invoke_ctr, G1_scratch);
if (ProfileInterpreter) {
- __ test_invocation_counter_for_mdp(G4_invoke_ctr, Lbcp, G3_scratch, Lforward);
+ __ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_scratch, Lforward);
if (UseOnStackReplacement) {
__ test_backedge_count_for_osr(O2_bumped_count, O0_cur_bcp, G3_scratch);
}
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -819,7 +819,7 @@
// Set the method data pointer for the current bcp.
void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
assert(ProfileInterpreter, "must be profiling interpreter");
- Label zero_continue;
+ Label set_mdp;
push(rax);
push(rbx);
@@ -827,21 +827,17 @@
// Test MDO to avoid the call if it is NULL.
movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset())));
testptr(rax, rax);
- jcc(Assembler::zero, zero_continue);
-
+ jcc(Assembler::zero, set_mdp);
// rbx,: method
// rsi: bcp
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, rsi);
// rax,: mdi
-
+ // mdo is guaranteed to be non-zero here, we checked for it before the call.
movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset())));
- testptr(rbx, rbx);
- jcc(Assembler::zero, zero_continue);
addptr(rbx, in_bytes(methodDataOopDesc::data_offset()));
- addptr(rbx, rax);
- movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx);
-
- bind(zero_continue);
+ addptr(rax, rbx);
+ bind(set_mdp);
+ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax);
pop(rbx);
pop(rax);
}
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -855,7 +855,7 @@
// Set the method data pointer for the current bcp.
void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
assert(ProfileInterpreter, "must be profiling interpreter");
- Label zero_continue;
+ Label set_mdp;
push(rax);
push(rbx);
@@ -863,21 +863,17 @@
// Test MDO to avoid the call if it is NULL.
movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset())));
testptr(rax, rax);
- jcc(Assembler::zero, zero_continue);
-
+ jcc(Assembler::zero, set_mdp);
// rbx: method
// r13: bcp
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, r13);
// rax: mdi
-
+ // mdo is guaranteed to be non-zero here, we checked for it before the call.
movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset())));
- testptr(rbx, rbx);
- jcc(Assembler::zero, zero_continue);
addptr(rbx, in_bytes(methodDataOopDesc::data_offset()));
- addptr(rbx, rax);
- movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx);
-
- bind(zero_continue);
+ addptr(rax, rbx);
+ bind(set_mdp);
+ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax);
pop(rbx);
pop(rax);
}
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -1367,15 +1367,8 @@
if (ProfileInterpreter) {
// We have decided to profile this method in the interpreter
__ bind(profile_method);
-
- __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), rsi, true);
-
- __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop
- __ movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset())));
- __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax);
- __ test_method_data_pointer(rax, profile_method_continue);
- __ addptr(rax, in_bytes(methodDataOopDesc::data_offset()));
- __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
+ __ set_method_data_pointer_for_bcp();
__ jmp(profile_method_continue);
}
// Handle overflow of counter and compile method
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -1383,20 +1383,8 @@
if (ProfileInterpreter) {
// We have decided to profile this method in the interpreter
__ bind(profile_method);
-
- __ call_VM(noreg,
- CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method),
- r13, true);
-
- __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop
- __ movptr(rax, Address(rbx,
- in_bytes(methodOopDesc::method_data_offset())));
- __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize),
- rax);
- __ test_method_data_pointer(rax, profile_method_continue);
- __ addptr(rax, in_bytes(methodDataOopDesc::data_offset()));
- __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize),
- rax);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
+ __ set_method_data_pointer_for_bcp();
__ jmp(profile_method_continue);
}
// Handle overflow of counter and compile method
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -1665,16 +1665,9 @@
if (ProfileInterpreter) {
// Out-of-line code to allocate method data oop.
__ bind(profile_method);
- __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method), rsi);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
__ load_unsigned_byte(rbx, Address(rsi, 0)); // restore target bytecode
- __ movptr(rcx, Address(rbp, method_offset));
- __ movptr(rcx, Address(rcx, in_bytes(methodOopDesc::method_data_offset())));
- __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx);
- __ test_method_data_pointer(rcx, dispatch);
- // offset non-null mdp by MDO::data_offset() + IR::profile_method()
- __ addptr(rcx, in_bytes(methodDataOopDesc::data_offset()));
- __ addptr(rcx, rax);
- __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rcx);
+ __ set_method_data_pointer_for_bcp();
__ jmp(dispatch);
}
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -1695,21 +1695,9 @@
if (ProfileInterpreter) {
// Out-of-line code to allocate method data oop.
__ bind(profile_method);
- __ call_VM(noreg,
- CAST_FROM_FN_PTR(address,
- InterpreterRuntime::profile_method), r13);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
__ load_unsigned_byte(rbx, Address(r13, 0)); // restore target bytecode
- __ movptr(rcx, Address(rbp, method_offset));
- __ movptr(rcx, Address(rcx,
- in_bytes(methodOopDesc::method_data_offset())));
- __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize),
- rcx);
- __ test_method_data_pointer(rcx, dispatch);
- // offset non-null mdp by MDO::data_offset() + IR::profile_method()
- __ addptr(rcx, in_bytes(methodDataOopDesc::data_offset()));
- __ addptr(rcx, rax);
- __ movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize),
- rcx);
+ __ set_method_data_pointer_for_bcp();
__ jmp(dispatch);
}
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -884,7 +884,7 @@
return mdo->bci_to_di(bci);
IRT_END
-IRT_ENTRY(jint, InterpreterRuntime::profile_method(JavaThread* thread, address cur_bcp))
+IRT_ENTRY(void, InterpreterRuntime::profile_method(JavaThread* thread))
// use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized
// flag, in case this method triggers classloading which will call into Java.
UnlockFlagSaver fs(thread);
@@ -893,16 +893,12 @@
frame fr = thread->last_frame();
assert(fr.is_interpreted_frame(), "must come from interpreter");
methodHandle method(thread, fr.interpreter_frame_method());
- int bci = method->bci_from(cur_bcp);
methodOopDesc::build_interpreter_method_data(method, THREAD);
if (HAS_PENDING_EXCEPTION) {
assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
CLEAR_PENDING_EXCEPTION;
// and fall through...
}
- methodDataOop mdo = method->method_data();
- if (mdo == NULL) return 0;
- return mdo->bci_to_di(bci);
IRT_END
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Mon Jan 10 03:58:07 2011 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Mon Jan 10 18:46:29 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -164,7 +164,7 @@
// Interpreter profiling support
static jint bcp_to_di(methodOopDesc* method, address cur_bcp);
- static jint profile_method(JavaThread* thread, address cur_bcp);
+ static void profile_method(JavaThread* thread);
static void update_mdp_for_ret(JavaThread* thread, int bci);
#ifdef ASSERT
static void verify_mdp(methodOopDesc* method, address bcp, address mdp);