--- old/src/hotspot/share/c1/c1_LIR.hpp 2019-03-11 14:25:10.002355932 +0100 +++ new/src/hotspot/share/c1/c1_LIR.hpp 2019-03-11 14:25:09.802355935 +0100 @@ -316,6 +316,7 @@ case T_INT: case T_ADDRESS: case T_OBJECT: + case T_VALUETYPE: case T_ARRAY: case T_METADATA: return single_size; @@ -466,6 +467,7 @@ case T_FLOAT: return LIR_OprDesc::float_type; case T_DOUBLE: return LIR_OprDesc::double_type; case T_OBJECT: + case T_VALUETYPE: case T_ARRAY: return LIR_OprDesc::object_type; case T_ADDRESS: return LIR_OprDesc::address_type; case T_METADATA: return LIR_OprDesc::metadata_type; @@ -651,6 +653,7 @@ LIR_Opr res; switch (type) { case T_OBJECT: // fall through + case T_VALUETYPE: // fall through case T_ARRAY: res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::object_type | @@ -756,6 +759,7 @@ static LIR_Opr stack(int index, BasicType type) { LIR_Opr res; switch (type) { + case T_VALUETYPE: // fall through case T_OBJECT: // fall through case T_ARRAY: res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | @@ -869,6 +873,7 @@ class LIR_OpUpdateCRC32; class LIR_OpLock; class LIR_OpTypeCheck; +class LIR_OpFlattenedStoreCheck; class LIR_OpCompareAndSwap; class LIR_OpProfileCall; class LIR_OpProfileType; @@ -983,6 +988,9 @@ , lir_checkcast , lir_store_check , end_opTypeCheck + , begin_opFlattenedStoreCheck + , lir_flattened_store_check + , end_opFlattenedStoreCheck , begin_opCompareAndSwap , lir_cas_long , lir_cas_obj @@ -1133,6 +1141,7 @@ virtual LIR_OpArrayCopy* as_OpArrayCopy() { return NULL; } virtual LIR_OpUpdateCRC32* as_OpUpdateCRC32() { return NULL; } virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; } + virtual LIR_OpFlattenedStoreCheck* as_OpFlattenedStoreCheck() { return NULL; } virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; } virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; } virtual LIR_OpProfileType* as_OpProfileType() { return NULL; } @@ -1264,7 +1273,10 @@ unaligned = 1 << 9, src_objarray = 1 << 10, dst_objarray = 1 << 11, - all_flags = (1 << 12) - 1 + always_slow_path = 1 << 12, + src_flat_check = 1 << 13, + dst_flat_check = 1 << 14, + all_flags = (1 << 15) - 1 }; LIR_OpArrayCopy(LIR_Opr src, LIR_Opr src_pos, LIR_Opr dst, LIR_Opr dst_pos, LIR_Opr length, LIR_Opr tmp, @@ -1557,11 +1569,12 @@ ciMethod* _profiled_method; int _profiled_bci; bool _should_profile; + bool _need_null_check; public: LIR_OpTypeCheck(LIR_Code code, LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, - CodeEmitInfo* info_for_exception, CodeEmitInfo* info_for_patch, CodeStub* stub); + CodeEmitInfo* info_for_exception, CodeEmitInfo* info_for_patch, CodeStub* stub, bool need_null_check = true); LIR_OpTypeCheck(LIR_Code code, LIR_Opr object, LIR_Opr array, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, CodeEmitInfo* info_for_exception); @@ -1583,13 +1596,41 @@ ciMethod* profiled_method() const { return _profiled_method; } int profiled_bci() const { return _profiled_bci; } bool should_profile() const { return _should_profile; } - + bool need_null_check() const { return _need_null_check; } virtual bool is_patching() { return _info_for_patch != NULL; } virtual void emit_code(LIR_Assembler* masm); virtual LIR_OpTypeCheck* as_OpTypeCheck() { return this; } void print_instr(outputStream* out) const PRODUCT_RETURN; }; +// LIR_OpFlattenedStoreCheck +class LIR_OpFlattenedStoreCheck: public LIR_Op { + friend class LIR_OpVisitState; + + private: + LIR_Opr _object; + ciKlass* _element_klass; + LIR_Opr _tmp1; + LIR_Opr _tmp2; + CodeEmitInfo* _info_for_exception; + CodeStub* _stub; + +public: + LIR_OpFlattenedStoreCheck(LIR_Opr object, ciKlass* element_klass, LIR_Opr tmp1, LIR_Opr tmp2, + CodeEmitInfo* info_for_exception); + + LIR_Opr object() const { return _object; } + LIR_Opr tmp1() const { return _tmp1; } + LIR_Opr tmp2() const { return _tmp2; } + ciKlass* element_klass() const { return _element_klass; } + CodeEmitInfo* info_for_exception() const { return _info_for_exception; } + CodeStub* stub() const { return _stub; } + + virtual void emit_code(LIR_Assembler* masm); + virtual LIR_OpFlattenedStoreCheck* as_OpFlattenedStoreCheck() { return this; } + virtual void print_instr(outputStream* out) const PRODUCT_RETURN; +}; + // LIR_Op2 class LIR_Op2: public LIR_Op { friend class LIR_OpVisitState; @@ -1782,20 +1823,23 @@ LIR_Opr _lock; LIR_Opr _scratch; CodeStub* _stub; + CodeStub* _throw_imse_stub; public: - LIR_OpLock(LIR_Code code, LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info) + LIR_OpLock(LIR_Code code, LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info, CodeStub* throw_imse_stub=NULL) : LIR_Op(code, LIR_OprFact::illegalOpr, info) , _hdr(hdr) , _obj(obj) , _lock(lock) , _scratch(scratch) - , _stub(stub) {} + , _stub(stub) + , _throw_imse_stub(throw_imse_stub) {} LIR_Opr hdr_opr() const { return _hdr; } LIR_Opr obj_opr() const { return _obj; } LIR_Opr lock_opr() const { return _lock; } LIR_Opr scratch_opr() const { return _scratch; } CodeStub* stub() const { return _stub; } + CodeStub* throw_imse_stub() const { return _throw_imse_stub; } virtual void emit_code(LIR_Assembler* masm); virtual LIR_OpLock* as_OpLock() { return this; } @@ -2230,7 +2274,7 @@ void load_stack_address_monitor(int monitor_ix, LIR_Opr dst) { append(new LIR_Op1(lir_monaddr, LIR_OprFact::intConst(monitor_ix), dst)); } void unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub); - void lock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info); + void lock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info, CodeStub* throw_imse_stub=NULL); void set_24bit_fpu() { append(new LIR_Op0(lir_24bit_FPU )); } void restore_fpu() { append(new LIR_Op0(lir_reset_FPU )); } @@ -2244,11 +2288,12 @@ void instanceof(LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, CodeEmitInfo* info_for_patch, ciMethod* profiled_method, int profiled_bci); void store_check(LIR_Opr object, LIR_Opr array, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, CodeEmitInfo* info_for_exception, ciMethod* profiled_method, int profiled_bci); + void flattened_store_check(LIR_Opr object, ciKlass* element_klass, LIR_Opr tmp1, LIR_Opr tmp2, CodeEmitInfo* info_for_exception); void checkcast (LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, CodeEmitInfo* info_for_exception, CodeEmitInfo* info_for_patch, CodeStub* stub, - ciMethod* profiled_method, int profiled_bci); + ciMethod* profiled_method, int profiled_bci, bool is_never_null); // MethodData* profiling void profile_call(ciMethod* method, int bci, ciMethod* callee, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* cha_klass) { append(new LIR_OpProfileCall(method, bci, callee, mdo, recv, t1, cha_klass));