mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
6809483: hotspot:::method_entry are not correctly generated for "method()V"
Reviewed-by: iveresov, twisti
This commit is contained in:
parent
34b0ff28e8
commit
84536ec263
10 changed files with 105 additions and 12 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -898,4 +898,4 @@ void Canonicalizer::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {}
|
||||||
void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
|
void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
|
||||||
void Canonicalizer::do_ProfileCall(ProfileCall* x) {}
|
void Canonicalizer::do_ProfileCall(ProfileCall* x) {}
|
||||||
void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {}
|
void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {}
|
||||||
|
void Canonicalizer::do_RuntimeCall(RuntimeCall* x) {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -102,6 +102,7 @@ class Canonicalizer: InstructionVisitor {
|
||||||
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
|
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
|
||||||
virtual void do_ProfileCall (ProfileCall* x);
|
virtual void do_ProfileCall (ProfileCall* x);
|
||||||
virtual void do_ProfileInvoke (ProfileInvoke* x);
|
virtual void do_ProfileInvoke (ProfileInvoke* x);
|
||||||
|
virtual void do_RuntimeCall (RuntimeCall* x);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_C1_C1_CANONICALIZER_HPP
|
#endif // SHARE_VM_C1_C1_CANONICALIZER_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1396,6 +1396,13 @@ void GraphBuilder::method_return(Value x) {
|
||||||
if (continuation() != NULL) {
|
if (continuation() != NULL) {
|
||||||
assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet");
|
assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet");
|
||||||
|
|
||||||
|
if (compilation()->env()->dtrace_method_probes()) {
|
||||||
|
// Report exit from inline methods
|
||||||
|
Values* args = new Values(1);
|
||||||
|
args->push(append(new Constant(new ObjectConstant(method()))));
|
||||||
|
append(new RuntimeCall(voidType, "dtrace_method_exit", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), args));
|
||||||
|
}
|
||||||
|
|
||||||
// If the inlined method is synchronized, the monitor must be
|
// If the inlined method is synchronized, the monitor must be
|
||||||
// released before we jump to the continuation block.
|
// released before we jump to the continuation block.
|
||||||
if (method()->is_synchronized()) {
|
if (method()->is_synchronized()) {
|
||||||
|
@ -3301,6 +3308,13 @@ void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool
|
||||||
Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI);
|
Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI);
|
||||||
assert(exception->is_pinned(), "must be");
|
assert(exception->is_pinned(), "must be");
|
||||||
|
|
||||||
|
if (compilation()->env()->dtrace_method_probes()) {
|
||||||
|
// Report exit from inline methods
|
||||||
|
Values* args = new Values(1);
|
||||||
|
args->push(append(new Constant(new ObjectConstant(method()))));
|
||||||
|
append(new RuntimeCall(voidType, "dtrace_method_exit", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), args));
|
||||||
|
}
|
||||||
|
|
||||||
int bci = SynchronizationEntryBCI;
|
int bci = SynchronizationEntryBCI;
|
||||||
if (lock) {
|
if (lock) {
|
||||||
assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing");
|
assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing");
|
||||||
|
@ -3486,6 +3500,11 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
|
||||||
inline_sync_entry(lock, sync_handler);
|
inline_sync_entry(lock, sync_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (compilation()->env()->dtrace_method_probes()) {
|
||||||
|
Values* args = new Values(1);
|
||||||
|
args->push(append(new Constant(new ObjectConstant(method()))));
|
||||||
|
append(new RuntimeCall(voidType, "dtrace_method_entry", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), args));
|
||||||
|
}
|
||||||
|
|
||||||
BlockBegin* callee_start_block = block_at(0);
|
BlockBegin* callee_start_block = block_at(0);
|
||||||
if (callee_start_block != NULL) {
|
if (callee_start_block != NULL) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -106,6 +106,7 @@ class UnsafePrefetchRead;
|
||||||
class UnsafePrefetchWrite;
|
class UnsafePrefetchWrite;
|
||||||
class ProfileCall;
|
class ProfileCall;
|
||||||
class ProfileInvoke;
|
class ProfileInvoke;
|
||||||
|
class RuntimeCall;
|
||||||
|
|
||||||
// A Value is a reference to the instruction creating the value
|
// A Value is a reference to the instruction creating the value
|
||||||
typedef Instruction* Value;
|
typedef Instruction* Value;
|
||||||
|
@ -202,6 +203,7 @@ class InstructionVisitor: public StackObj {
|
||||||
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0;
|
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0;
|
||||||
virtual void do_ProfileCall (ProfileCall* x) = 0;
|
virtual void do_ProfileCall (ProfileCall* x) = 0;
|
||||||
virtual void do_ProfileInvoke (ProfileInvoke* x) = 0;
|
virtual void do_ProfileInvoke (ProfileInvoke* x) = 0;
|
||||||
|
virtual void do_RuntimeCall (RuntimeCall* x) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2267,6 +2269,38 @@ LEAF(ProfileCall, Instruction)
|
||||||
virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); }
|
virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Call some C runtime function that doesn't safepoint,
|
||||||
|
// optionally passing the current thread as the first argument.
|
||||||
|
LEAF(RuntimeCall, Instruction)
|
||||||
|
private:
|
||||||
|
const char* _entry_name;
|
||||||
|
address _entry;
|
||||||
|
Values* _args;
|
||||||
|
bool _pass_thread; // Pass the JavaThread* as an implicit first argument
|
||||||
|
|
||||||
|
public:
|
||||||
|
RuntimeCall(ValueType* type, const char* entry_name, address entry, Values* args, bool pass_thread = true)
|
||||||
|
: Instruction(type)
|
||||||
|
, _entry(entry)
|
||||||
|
, _args(args)
|
||||||
|
, _entry_name(entry_name)
|
||||||
|
, _pass_thread(pass_thread) {
|
||||||
|
ASSERT_VALUES
|
||||||
|
pin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* entry_name() const { return _entry_name; }
|
||||||
|
address entry() const { return _entry; }
|
||||||
|
int number_of_arguments() const { return _args->length(); }
|
||||||
|
Value argument_at(int i) const { return _args->at(i); }
|
||||||
|
bool pass_thread() const { return _pass_thread; }
|
||||||
|
|
||||||
|
virtual void input_values_do(ValueVisitor* f) {
|
||||||
|
for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Use to trip invocation counter of an inlined method
|
// Use to trip invocation counter of an inlined method
|
||||||
|
|
||||||
LEAF(ProfileInvoke, Instruction)
|
LEAF(ProfileInvoke, Instruction)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -841,4 +841,13 @@ void InstructionPrinter::do_ProfileInvoke(ProfileInvoke* x) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InstructionPrinter::do_RuntimeCall(RuntimeCall* x) {
|
||||||
|
output()->print("call_rt %s(", x->entry_name());
|
||||||
|
for (int i = 0; i < x->number_of_arguments(); i++) {
|
||||||
|
if (i > 0) output()->print(", ");
|
||||||
|
print_value(x->argument_at(i));
|
||||||
|
}
|
||||||
|
output()->put(')');
|
||||||
|
}
|
||||||
|
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -131,6 +131,7 @@ class InstructionPrinter: public InstructionVisitor {
|
||||||
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
|
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
|
||||||
virtual void do_ProfileCall (ProfileCall* x);
|
virtual void do_ProfileCall (ProfileCall* x);
|
||||||
virtual void do_ProfileInvoke (ProfileInvoke* x);
|
virtual void do_ProfileInvoke (ProfileInvoke* x);
|
||||||
|
virtual void do_RuntimeCall (RuntimeCall* x);
|
||||||
};
|
};
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2741,6 +2741,31 @@ void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LIRGenerator::do_RuntimeCall(RuntimeCall* x) {
|
||||||
|
LIR_OprList* args = new LIR_OprList(x->number_of_arguments());
|
||||||
|
BasicTypeList* signature = new BasicTypeList(x->number_of_arguments());
|
||||||
|
|
||||||
|
if (x->pass_thread()) {
|
||||||
|
signature->append(T_ADDRESS);
|
||||||
|
args->append(getThreadPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < x->number_of_arguments(); i++) {
|
||||||
|
Value a = x->argument_at(i);
|
||||||
|
LIRItem* item = new LIRItem(a, this);
|
||||||
|
item->load_item();
|
||||||
|
args->append(item->result());
|
||||||
|
signature->append(as_BasicType(a->type()));
|
||||||
|
}
|
||||||
|
|
||||||
|
LIR_Opr result = call_runtime(signature, args, x->entry(), x->type(), NULL);
|
||||||
|
if (x->type() == voidType) {
|
||||||
|
set_no_result(x);
|
||||||
|
} else {
|
||||||
|
__ move(result, rlock_result(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
|
LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
|
||||||
LIRItemList args(1);
|
LIRItemList args(1);
|
||||||
LIRItem value(arg1, this);
|
LIRItem value(arg1, this);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -522,6 +522,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
|
||||||
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
|
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
|
||||||
virtual void do_ProfileCall (ProfileCall* x);
|
virtual void do_ProfileCall (ProfileCall* x);
|
||||||
virtual void do_ProfileInvoke (ProfileInvoke* x);
|
virtual void do_ProfileInvoke (ProfileInvoke* x);
|
||||||
|
virtual void do_RuntimeCall (RuntimeCall* x);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -496,6 +496,7 @@ public:
|
||||||
void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
|
void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
|
||||||
void do_ProfileCall (ProfileCall* x);
|
void do_ProfileCall (ProfileCall* x);
|
||||||
void do_ProfileInvoke (ProfileInvoke* x);
|
void do_ProfileInvoke (ProfileInvoke* x);
|
||||||
|
void do_RuntimeCall (RuntimeCall* x);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -664,6 +665,7 @@ void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {}
|
||||||
void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
|
void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
|
||||||
void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); }
|
void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); }
|
||||||
void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {}
|
void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {}
|
||||||
|
void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {}
|
||||||
|
|
||||||
|
|
||||||
void NullCheckEliminator::visit(Value* p) {
|
void NullCheckEliminator::visit(Value* p) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -192,11 +192,12 @@ class ValueNumberingVisitor: public InstructionVisitor {
|
||||||
void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }
|
void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }
|
||||||
void do_RoundFP (RoundFP* x) { /* nothing to do */ }
|
void do_RoundFP (RoundFP* x) { /* nothing to do */ }
|
||||||
void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ }
|
void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ }
|
||||||
void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ };
|
|
||||||
void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }
|
void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }
|
||||||
void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ }
|
void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ }
|
||||||
void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }
|
void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }
|
||||||
void do_ProfileCall (ProfileCall* x) { /* nothing to do */ }
|
void do_ProfileCall (ProfileCall* x) { /* nothing to do */ }
|
||||||
|
void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ };
|
||||||
|
void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue