aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/c1/c1_Instruction.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/vm/c1/c1_Instruction.hpp')
-rw-r--r--src/share/vm/c1/c1_Instruction.hpp101
1 files changed, 70 insertions, 31 deletions
diff --git a/src/share/vm/c1/c1_Instruction.hpp b/src/share/vm/c1/c1_Instruction.hpp
index 9563b720a..466d814c6 100644
--- a/src/share/vm/c1/c1_Instruction.hpp
+++ b/src/share/vm/c1/c1_Instruction.hpp
@@ -322,6 +322,36 @@ class Instruction: public CompilationResourceObj {
_type = type;
}
+ // Helper class to keep track of which arguments need a null check
+ class ArgsNonNullState {
+ private:
+ int _nonnull_state; // mask identifying which args are nonnull
+ public:
+ ArgsNonNullState()
+ : _nonnull_state(AllBits) {}
+
+ // Does argument number i needs a null check?
+ bool arg_needs_null_check(int i) const {
+ // No data is kept for arguments starting at position 33 so
+ // conservatively assume that they need a null check.
+ if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) {
+ return is_set_nth_bit(_nonnull_state, i);
+ }
+ return true;
+ }
+
+ // Set whether argument number i needs a null check or not
+ void set_arg_needs_null_check(int i, bool check) {
+ if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) {
+ if (check) {
+ _nonnull_state |= nth_bit(i);
+ } else {
+ _nonnull_state &= ~(nth_bit(i));
+ }
+ }
+ }
+ };
+
public:
void* operator new(size_t size) throw() {
Compilation* c = Compilation::current();
@@ -566,7 +596,7 @@ class Instruction: public CompilationResourceObj {
virtual void other_values_do(ValueVisitor* f) { /* usually no other - override on demand */ }
void values_do(ValueVisitor* f) { input_values_do(f); state_values_do(f); other_values_do(f); }
- virtual ciType* exact_type() const { return NULL; }
+ virtual ciType* exact_type() const;
virtual ciType* declared_type() const { return NULL; }
// hashing
@@ -689,7 +719,6 @@ LEAF(Local, Instruction)
int java_index() const { return _java_index; }
virtual ciType* declared_type() const { return _declared_type; }
- virtual ciType* exact_type() const;
// generic
virtual void input_values_do(ValueVisitor* f) { /* no values */ }
@@ -806,7 +835,6 @@ LEAF(LoadField, AccessField)
{}
ciType* declared_type() const;
- ciType* exact_type() const;
// generic
HASHING2(LoadField, !needs_patching() && !field()->is_volatile(), obj()->subst(), offset()) // cannot be eliminated if needs patching or if volatile
@@ -1299,6 +1327,7 @@ BASE(NewArray, StateSplit)
virtual bool needs_exception_state() const { return false; }
+ ciType* exact_type() const { return NULL; }
ciType* declared_type() const;
// generic
@@ -1422,7 +1451,6 @@ LEAF(CheckCast, TypeCheck)
}
ciType* declared_type() const;
- ciType* exact_type() const;
};
@@ -1490,7 +1518,7 @@ LEAF(Intrinsic, StateSplit)
vmIntrinsics::ID _id;
Values* _args;
Value _recv;
- int _nonnull_state; // mask identifying which args are nonnull
+ ArgsNonNullState _nonnull_state;
public:
// preserves_state can be set to true for Intrinsics
@@ -1511,7 +1539,6 @@ LEAF(Intrinsic, StateSplit)
, _id(id)
, _args(args)
, _recv(NULL)
- , _nonnull_state(AllBits)
{
assert(args != NULL, "args must exist");
ASSERT_VALUES
@@ -1537,21 +1564,12 @@ LEAF(Intrinsic, StateSplit)
Value receiver() const { assert(has_receiver(), "must have receiver"); return _recv; }
bool preserves_state() const { return check_flag(PreservesStateFlag); }
- bool arg_needs_null_check(int i) {
- if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) {
- return is_set_nth_bit(_nonnull_state, i);
- }
- return true;
+ bool arg_needs_null_check(int i) const {
+ return _nonnull_state.arg_needs_null_check(i);
}
void set_arg_needs_null_check(int i, bool check) {
- if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) {
- if (check) {
- _nonnull_state |= nth_bit(i);
- } else {
- _nonnull_state &= ~(nth_bit(i));
- }
- }
+ _nonnull_state.set_arg_needs_null_check(i, check);
}
// generic
@@ -2450,34 +2468,55 @@ LEAF(UnsafePrefetchWrite, UnsafePrefetch)
LEAF(ProfileCall, Instruction)
private:
- ciMethod* _method;
- int _bci_of_invoke;
- ciMethod* _callee; // the method that is called at the given bci
- Value _recv;
- ciKlass* _known_holder;
+ ciMethod* _method;
+ int _bci_of_invoke;
+ ciMethod* _callee; // the method that is called at the given bci
+ Value _recv;
+ ciKlass* _known_holder;
+ Values* _obj_args; // arguments for type profiling
+ ArgsNonNullState _nonnull_state; // Do we know whether some arguments are never null?
+ bool _inlined; // Are we profiling a call that is inlined
public:
- ProfileCall(ciMethod* method, int bci, ciMethod* callee, Value recv, ciKlass* known_holder)
+ ProfileCall(ciMethod* method, int bci, ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined)
: Instruction(voidType)
, _method(method)
, _bci_of_invoke(bci)
, _callee(callee)
, _recv(recv)
, _known_holder(known_holder)
+ , _obj_args(obj_args)
+ , _inlined(inlined)
{
// The ProfileCall has side-effects and must occur precisely where located
pin();
}
- ciMethod* method() { return _method; }
- int bci_of_invoke() { return _bci_of_invoke; }
- ciMethod* callee() { return _callee; }
- Value recv() { return _recv; }
- ciKlass* known_holder() { return _known_holder; }
+ ciMethod* method() const { return _method; }
+ int bci_of_invoke() const { return _bci_of_invoke; }
+ ciMethod* callee() const { return _callee; }
+ Value recv() const { return _recv; }
+ ciKlass* known_holder() const { return _known_holder; }
+ int nb_profiled_args() const { return _obj_args == NULL ? 0 : _obj_args->length(); }
+ Value profiled_arg_at(int i) const { return _obj_args->at(i); }
+ bool arg_needs_null_check(int i) const {
+ return _nonnull_state.arg_needs_null_check(i);
+ }
+ bool inlined() const { return _inlined; }
- virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); }
-};
+ void set_arg_needs_null_check(int i, bool check) {
+ _nonnull_state.set_arg_needs_null_check(i, check);
+ }
+ virtual void input_values_do(ValueVisitor* f) {
+ if (_recv != NULL) {
+ f->visit(&_recv);
+ }
+ for (int i = 0; i < nb_profiled_args(); i++) {
+ f->visit(_obj_args->adr_at(i));
+ }
+ }
+};
// Call some C runtime function that doesn't safepoint,
// optionally passing the current thread as the first argument.