< 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 >