src/share/vm/c1/c1_Instruction.hpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/c1/c1_Instruction.hpp
src/share/vm/c1/c1_Instruction.hpp
Print this page
rev 5240 : 8023657: New type profiling points: arguments to call
Summary: x86 interpreter and c1 type profiling for arguments at calls
Reviewed-by:
*** 320,329 ****
--- 320,354 ----
void set_type(ValueType* type) {
assert(type != NULL, "type must exist");
_type = type;
}
+ class ArgsNonNullState {
+ private:
+ int _nonnull_state; // mask identifying which args are nonnull
+ public:
+ ArgsNonNullState()
+ : _nonnull_state(AllBits) {}
+
+ bool arg_needs_null_check(int i) const {
+ if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) {
+ return is_set_nth_bit(_nonnull_state, i);
+ }
+ return true;
+ }
+
+ 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();
void* res = c->arena()->Amalloc(size);
((Instruction*)res)->_id = c->get_next_id();
*** 564,574 ****
virtual void input_values_do(ValueVisitor* f) = 0;
virtual void state_values_do(ValueVisitor* f);
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* declared_type() const { return NULL; }
// hashing
virtual const char* name() const = 0;
HASHING1(Instruction, false, id()) // hashing disabled by default
--- 589,599 ----
virtual void input_values_do(ValueVisitor* f) = 0;
virtual void state_values_do(ValueVisitor* f);
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;
virtual ciType* declared_type() const { return NULL; }
// hashing
virtual const char* name() const = 0;
HASHING1(Instruction, false, id()) // hashing disabled by default
*** 687,697 ****
// accessors
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 */ }
};
--- 712,721 ----
*** 804,814 ****
ValueStack* state_before, bool needs_patching)
: AccessField(obj, offset, field, is_static, state_before, needs_patching)
{}
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
};
--- 828,837 ----
*** 1297,1306 ****
--- 1320,1330 ----
// accessors
Value length() const { return _length; }
virtual bool needs_exception_state() const { return false; }
+ ciType* exact_type() const { return NULL; }
ciType* declared_type() const;
// generic
virtual bool can_trap() const { return true; }
virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_length); }
*** 1420,1430 ****
bool is_incompatible_class_change_check() const {
return check_flag(ThrowIncompatibleClassChangeErrorFlag);
}
ciType* declared_type() const;
- ciType* exact_type() const;
};
LEAF(InstanceOf, TypeCheck)
public:
--- 1444,1453 ----
*** 1488,1498 ****
LEAF(Intrinsic, StateSplit)
private:
vmIntrinsics::ID _id;
Values* _args;
Value _recv;
! int _nonnull_state; // mask identifying which args are nonnull
public:
// preserves_state can be set to true for Intrinsics
// which are guaranteed to preserve register state across any slow
// cases; setting it to true does not mean that the Intrinsic can
--- 1511,1521 ----
LEAF(Intrinsic, StateSplit)
private:
vmIntrinsics::ID _id;
Values* _args;
Value _recv;
! ArgsNonNullState _nonnull_state;
public:
// preserves_state can be set to true for Intrinsics
// which are guaranteed to preserve register state across any slow
// cases; setting it to true does not mean that the Intrinsic can
*** 1509,1519 ****
bool cantrap = true)
: StateSplit(type, state_before)
, _id(id)
, _args(args)
, _recv(NULL)
- , _nonnull_state(AllBits)
{
assert(args != NULL, "args must exist");
ASSERT_VALUES
set_flag(PreservesStateFlag, preserves_state);
set_flag(CanTrapFlag, cantrap);
--- 1532,1541 ----
*** 1535,1559 ****
bool has_receiver() const { return (_recv != NULL); }
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;
}
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));
! }
! }
}
// generic
virtual bool can_trap() const { return check_flag(CanTrapFlag); }
virtual void input_values_do(ValueVisitor* f) {
--- 1557,1572 ----
bool has_receiver() const { return (_recv != NULL); }
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) const {
! return _nonnull_state.arg_needs_null_check(i);
}
void set_arg_needs_null_check(int i, bool check) {
! _nonnull_state.set_arg_needs_null_check(i, check);
}
// generic
virtual bool can_trap() const { return check_flag(CanTrapFlag); }
virtual void input_values_do(ValueVisitor* f) {
*** 2453,2485 ****
ciMethod* _method;
int _bci_of_invoke;
ciMethod* _callee; // the method that is called at the given bci
Value _recv;
ciKlass* _known_holder;
public:
! ProfileCall(ciMethod* method, int bci, ciMethod* callee, Value recv, ciKlass* known_holder)
: Instruction(voidType)
, _method(method)
, _bci_of_invoke(bci)
, _callee(callee)
, _recv(recv)
, _known_holder(known_holder)
{
// 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; }
! 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:
--- 2466,2515 ----
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, 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() 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; }
! 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.
LEAF(RuntimeCall, Instruction)
private:
src/share/vm/c1/c1_Instruction.hpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File