src/share/vm/c1/c1_Instruction.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/c1/c1_Instruction.hpp	Wed Oct  2 17:55:36 2013
--- new/src/share/vm/c1/c1_Instruction.hpp	Wed Oct  2 17:55:36 2013

*** 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 **** --- 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 { return NULL; } virtual ciType* declared_type() const { return NULL; } // hashing virtual const char* name() const = 0; HASHING1(Instruction, false, id()) // hashing disabled by default
*** 687,697 **** --- 712,721 ---- // 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 */ } };
*** 804,814 **** --- 828,837 ---- 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 };
*** 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 **** --- 1444,1453 ---- bool is_incompatible_class_change_check() const { return check_flag(ThrowIncompatibleClassChangeErrorFlag); } ciType* declared_type() const; ciType* exact_type() const; }; LEAF(InstanceOf, TypeCheck) public:
*** 1488,1498 **** --- 1511,1521 ---- LEAF(Intrinsic, StateSplit) private: 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 // which are guaranteed to preserve register state across any slow // cases; setting it to true does not mean that the Intrinsic can
*** 1509,1519 **** --- 1532,1541 ---- 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);
*** 1535,1559 **** --- 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 { if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { return is_set_nth_bit(_nonnull_state, i); } return true; + 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 virtual bool can_trap() const { return check_flag(CanTrapFlag); } virtual void input_values_do(ValueVisitor* f) {
*** 2453,2485 **** --- 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; } ! 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. LEAF(RuntimeCall, Instruction) private:

src/share/vm/c1/c1_Instruction.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File