4930919: race condition in MDO creation at back branch locations
Reuse set_method_data_for_bcp() to setup mdp after MDO creation. Reviewed-by: kvn, never
This commit is contained in:
parent
595eda12a4
commit
6a80d2126c
@ -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 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
|
||||
// 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 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
|
||||
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::verify_method_data_pointer() {
|
||||
}
|
||||
|
||||
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 @@ void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocat
|
||||
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);
|
||||
|
@ -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 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
|
||||
#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,
|
||||
|
@ -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 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
// 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();
|
||||
}
|
||||
|
@ -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 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
|
||||
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);
|
||||
}
|
||||
|
@ -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 @@ void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& ze
|
||||
// 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 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
|
||||
// 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);
|
||||
}
|
||||
|
@ -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 @@ void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
|
||||
// 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 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
|
||||
// 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);
|
||||
}
|
||||
|
@ -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 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
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
|
||||
|
@ -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 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
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
|
||||
|
@ -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 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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 @@ IRT_LEAF(jint, InterpreterRuntime::bcp_to_di(methodOopDesc* method, address cur_
|
||||
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 @@ IRT_ENTRY(jint, InterpreterRuntime::profile_method(JavaThread* thread, address c
|
||||
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
|
||||
|
||||
|
||||
|
@ -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 @@ class InterpreterRuntime: AllStatic {
|
||||
|
||||
// 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user