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 5349 : 8023657: New type profiling points: arguments to call
Summary: x86 interpreter and c1 type profiling for arguments at calls
Reviewed-by:

*** 320,329 **** --- 320,359 ---- void set_type(ValueType* type) { assert(type != NULL, "type must exist"); _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(); 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 --- 594,604 ---- 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 */ } }; --- 717,726 ----
*** 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 }; --- 833,842 ----
*** 1297,1306 **** --- 1325,1335 ---- // 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: --- 1449,1458 ----
*** 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 --- 1516,1526 ---- 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); --- 1537,1546 ----
*** 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) { --- 1562,1577 ---- 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: --- 2471,2524 ---- 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