< prev index next >
src/hotspot/share/c1/c1_LIR.cpp
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
@@ -105,10 +105,11 @@
//---------------------------------------------------
char LIR_OprDesc::type_char(BasicType t) {
switch (t) {
case T_ARRAY:
+ case T_VALUETYPE:
t = T_OBJECT;
case T_BOOLEAN:
case T_CHAR:
case T_FLOAT:
case T_DOUBLE:
@@ -163,10 +164,11 @@
case T_INT:
case T_ADDRESS:
case T_OBJECT:
case T_METADATA:
case T_ARRAY:
+ case T_VALUETYPE:
assert((kindfield == cpu_register || kindfield == stack_value) &&
size_field() == single_size, "must match");
break;
case T_ILLEGAL:
@@ -309,11 +311,11 @@
LIR_OpTypeCheck::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)
+ CodeStub* stub, bool need_null_check)
: LIR_Op(code, result, NULL)
, _object(object)
, _array(LIR_OprFact::illegalOpr)
, _klass(klass)
@@ -325,10 +327,11 @@
, _info_for_exception(info_for_exception)
, _stub(stub)
, _profiled_method(NULL)
, _profiled_bci(-1)
, _should_profile(false)
+ , _need_null_check(need_null_check)
{
if (code == lir_checkcast) {
assert(info_for_exception != NULL, "checkcast throws exceptions");
} else if (code == lir_instanceof) {
assert(info_for_exception == NULL, "instanceof throws no exceptions");
@@ -352,19 +355,32 @@
, _info_for_exception(info_for_exception)
, _stub(NULL)
, _profiled_method(NULL)
, _profiled_bci(-1)
, _should_profile(false)
+ , _need_null_check(true)
{
if (code == lir_store_check) {
_stub = new ArrayStoreExceptionStub(object, info_for_exception);
assert(info_for_exception != NULL, "store_check throws exceptions");
} else {
ShouldNotReachHere();
}
}
+LIR_OpFlattenedStoreCheck::LIR_OpFlattenedStoreCheck(LIR_Opr object, ciKlass* element_klass,
+ LIR_Opr tmp1, LIR_Opr tmp2,
+ CodeEmitInfo* info_for_exception)
+ : LIR_Op(lir_flattened_store_check, LIR_OprFact::illegalOpr, NULL)
+ , _object(object)
+ , _element_klass(element_klass)
+ , _tmp1(tmp1)
+ , _tmp2(tmp2)
+ , _info_for_exception(info_for_exception)
+{
+ _stub = new ArrayStoreExceptionStub(object, info_for_exception);
+}
LIR_OpArrayCopy::LIR_OpArrayCopy(LIR_Opr src, LIR_Opr src_pos, LIR_Opr dst, LIR_Opr dst_pos, LIR_Opr length,
LIR_Opr tmp, ciArrayKlass* expected_type, int flags, CodeEmitInfo* info)
: LIR_Op(lir_arraycopy, LIR_OprFact::illegalOpr, info)
, _src(src)
@@ -815,10 +831,11 @@
if (opLock->_scratch->is_valid()) do_temp(opLock->_scratch);
assert(opLock->_result->is_illegal(), "unused");
do_stub(opLock->_stub);
+ do_stub(opLock->_throw_imse_stub);
break;
}
@@ -851,10 +868,23 @@
if (opTypeCheck->_result->is_valid()) do_output(opTypeCheck->_result);
do_stub(opTypeCheck->_stub);
break;
}
+// LIR_OpFlattenedStoreCheck
+ case lir_flattened_store_check: {
+ assert(op->as_OpFlattenedStoreCheck() != NULL, "must be");
+ LIR_OpFlattenedStoreCheck* opFlattenedStoreCheck = (LIR_OpFlattenedStoreCheck*)op;
+
+ if (opFlattenedStoreCheck->_info_for_exception) do_info(opFlattenedStoreCheck->_info_for_exception);
+ if (opFlattenedStoreCheck->_object->is_valid()) do_temp(opFlattenedStoreCheck->_object);
+ if (opFlattenedStoreCheck->_tmp1->is_valid()) do_temp(opFlattenedStoreCheck->_tmp1);
+ if (opFlattenedStoreCheck->_tmp2->is_valid()) do_temp(opFlattenedStoreCheck->_tmp2);
+ do_stub(opFlattenedStoreCheck->_stub);
+ break;
+ }
+
// LIR_OpCompareAndSwap
case lir_cas_long:
case lir_cas_obj:
case lir_cas_int: {
assert(op->as_OpCompareAndSwap() != NULL, "must be");
@@ -1038,10 +1068,17 @@
if (stub()) {
masm->append_code_stub(stub());
}
}
+void LIR_OpFlattenedStoreCheck::emit_code(LIR_Assembler* masm) {
+ masm->emit_opFlattenedStoreCheck(this);
+ if (stub()) {
+ masm->append_code_stub(stub());
+ }
+}
+
void LIR_OpCompareAndSwap::emit_code(LIR_Assembler* masm) {
masm->emit_compare_and_swap(this);
}
void LIR_Op3::emit_code(LIR_Assembler* masm) {
@@ -1051,10 +1088,13 @@
void LIR_OpLock::emit_code(LIR_Assembler* masm) {
masm->emit_lock(this);
if (stub()) {
masm->append_code_stub(stub());
}
+ if (throw_imse_stub()) {
+ masm->append_code_stub(throw_imse_stub());
+ }
}
#ifdef ASSERT
void LIR_OpAssert::emit_code(LIR_Assembler* masm) {
masm->emit_assert(this);
@@ -1352,19 +1392,20 @@
left,
right,
dst));
}
-void LIR_List::lock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info) {
+void LIR_List::lock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info, CodeStub* throw_imse_stub) {
append(new LIR_OpLock(
lir_lock,
hdr,
obj,
lock,
scratch,
stub,
- info));
+ info,
+ throw_imse_stub));
}
void LIR_List::unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub) {
append(new LIR_OpLock(
lir_unlock,
@@ -1385,13 +1426,17 @@
void LIR_List::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) {
+ // If klass is non-nullable, LIRGenerator::do_CheckCast has already performed null-check
+ // on the object.
+ bool need_null_check = !is_never_null;
LIR_OpTypeCheck* c = new LIR_OpTypeCheck(lir_checkcast, result, object, klass,
- tmp1, tmp2, tmp3, fast_check, info_for_exception, info_for_patch, stub);
+ tmp1, tmp2, tmp3, fast_check, info_for_exception, info_for_patch, stub,
+ need_null_check);
if (profiled_method != NULL) {
c->set_profiled_method(profiled_method);
c->set_profiled_bci(profiled_bci);
c->set_should_profile(true);
}
@@ -1430,10 +1475,17 @@
// Emit an implicit null check
append(new LIR_Op1(lir_null_check, opr, info));
}
}
+void LIR_List::flattened_store_check(LIR_Opr object, ciKlass* element_klass,
+ LIR_Opr tmp1, LIR_Opr tmp2,
+ CodeEmitInfo* info_for_exception) {
+ LIR_OpFlattenedStoreCheck* c = new LIR_OpFlattenedStoreCheck(object, element_klass, tmp1, tmp2, info_for_exception);
+ append(c);
+}
+
void LIR_List::cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
LIR_Opr t1, LIR_Opr t2, LIR_Opr result) {
append(new LIR_OpCompareAndSwap(lir_cas_long, addr, cmp_value, new_value, t1, t2, result));
}
@@ -1722,10 +1774,12 @@
case lir_delay_slot: s = "delay"; break;
// LIR_OpTypeCheck
case lir_instanceof: s = "instanceof"; break;
case lir_checkcast: s = "checkcast"; break;
case lir_store_check: s = "store_check"; break;
+ // LIR_OpFlattenedStoreCheck
+ case lir_flattened_store_check: s = "flattened_store_check"; break;
// LIR_OpCompareAndSwap
case lir_cas_long: s = "cas_long"; break;
case lir_cas_obj: s = "cas_obj"; break;
case lir_cas_int: s = "cas_int"; break;
// LIR_OpProfileCall
@@ -1967,10 +2021,18 @@
tmp3()->print(out); out->print(" ");
result_opr()->print(out); out->print(" ");
if (info_for_exception() != NULL) out->print(" [bci:%d]", info_for_exception()->stack()->bci());
}
+void LIR_OpFlattenedStoreCheck::print_instr(outputStream* out) const {
+ object()->print(out); out->print(" ");
+ element_klass()->print_name_on(out); out->print(" ");
+ tmp1()->print(out); out->print(" ");
+ tmp2()->print(out); out->print(" ");
+ if (info_for_exception() != NULL) out->print(" [bci:%d]", info_for_exception()->stack()->bci());
+}
+
// LIR_Op3
void LIR_Op3::print_instr(outputStream* out) const {
in_opr1()->print(out); out->print(" ");
in_opr2()->print(out); out->print(" ");
< prev index next >