1 /*
   2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_GC_SHARED_C1_BARRIERSETC1_HPP
  26 #define SHARE_GC_SHARED_C1_BARRIERSETC1_HPP
  27 
  28 #include "c1/c1_Decorators.hpp"
  29 #include "c1/c1_LIRGenerator.hpp"
  30 #include "c1/c1_Instruction.hpp"
  31 #include "c1/c1_LIR.hpp"
  32 #include "memory/allocation.hpp"
  33 
  34 class LIRGenerator;
  35 class LIRItem;
  36 
  37 // The LIRAddressOpr comprises either a LIRItem or a LIR_Opr to describe elements
  38 // of an access in the C1 Access API. Both of them allow asking for the opr() which
  39 // will correspond to either _item.result() or _opr if there is no _item.
  40 class LIRAddressOpr: public StackObj {
  41   LIRItem* _item;
  42   LIR_Opr  _opr;
  43 public:
  44   LIRAddressOpr(LIRItem& item) : _item(&item), _opr(NULL) {}
  45   LIRAddressOpr(LIR_Opr opr) : _item(NULL), _opr(opr) {}
  46   LIRAddressOpr(const LIRAddressOpr& other) : _item(other._item), _opr(other._opr) {}
  47 
  48   LIRItem& item() const {
  49     assert(_item != NULL, "sanity");
  50     return *_item;
  51   }
  52 
  53   LIR_Opr opr() const {
  54     if (_item == NULL) {
  55       return _opr;
  56     } else {
  57       return _item->result();
  58     }
  59   }
  60 };
  61 
  62 // The LIRAccess class wraps shared context parameters required for performing
  63 // the right access in C1. This includes the address of the offset and the decorators.
  64 class LIRAccess: public StackObj {
  65   LIRGenerator* _gen;
  66   DecoratorSet  _decorators;
  67   LIRAddressOpr _base;
  68   LIRAddressOpr _offset;
  69   BasicType     _type;
  70   LIR_Opr       _resolved_addr;
  71   CodeEmitInfo* _patch_emit_info;
  72   CodeEmitInfo* _access_emit_info;
  73 
  74 public:
  75   LIRAccess(LIRGenerator* gen, DecoratorSet decorators,
  76             LIRAddressOpr base, LIRAddressOpr offset, BasicType type,
  77             CodeEmitInfo* patch_emit_info = NULL, CodeEmitInfo* access_emit_info = NULL) :
  78     _gen(gen),
  79     _decorators(AccessInternal::decorator_fixup(decorators)),
  80     _base(base),
  81     _offset(offset),
  82     _type(type),
  83     _resolved_addr(NULL),
  84     _patch_emit_info(patch_emit_info),
  85     _access_emit_info(access_emit_info) {}
  86 
  87   void load_base()   { _base.item().load_item(); }
  88   void load_offset() { _offset.item().load_nonconstant(); }
  89 
  90   void load_address() {
  91     load_base();
  92     load_offset();
  93   }
  94 
  95   LIRGenerator* gen() const              { return _gen; }
  96   CodeEmitInfo*& patch_emit_info()       { return _patch_emit_info; }
  97   CodeEmitInfo*& access_emit_info()      { return _access_emit_info; }
  98   LIRAddressOpr& base()                  { return _base; }
  99   LIRAddressOpr& offset()                { return _offset; }
 100   BasicType type() const                 { return _type; }
 101   LIR_Opr resolved_addr() const          { return _resolved_addr; }
 102   void set_resolved_addr(LIR_Opr addr)   { _resolved_addr = addr; }
 103   bool is_oop() const                  { return _type == T_ARRAY || _type == T_OBJECT || _type == T_VALUETYPE; }
 104   DecoratorSet decorators() const        { return _decorators; }
 105   void clear_decorators(DecoratorSet ds) { _decorators &= ~ds; }
 106   bool is_raw() const                    { return (_decorators & AS_RAW) != 0; }
 107 };
 108 
 109 // The BarrierSetC1 class is the main entry point for the GC backend of the Access API in C1.
 110 // It is called by the LIRGenerator::access_* functions, which is the main entry poing for
 111 // access calls in C1.
 112 
 113 class BarrierSetC1: public CHeapObj<mtGC> {
 114 protected:
 115   virtual LIR_Opr resolve_address(LIRAccess& access, bool resolve_in_register);
 116 
 117   virtual void generate_referent_check(LIRAccess& access, LabelObj* cont);
 118 
 119   // Accesses with resolved address
 120   virtual void store_at_resolved(LIRAccess& access, LIR_Opr value);
 121   virtual void load_at_resolved(LIRAccess& access, LIR_Opr result);
 122 
 123   virtual LIR_Opr atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value);
 124 
 125   virtual LIR_Opr atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value);
 126   virtual LIR_Opr atomic_add_at_resolved(LIRAccess& access, LIRItem& value);
 127 
 128 public:
 129   virtual void store_at(LIRAccess& access, LIR_Opr value);
 130   virtual void load_at(LIRAccess& access, LIR_Opr result);
 131   virtual void load(LIRAccess& access, LIR_Opr result);
 132 
 133   virtual LIR_Opr atomic_cmpxchg_at(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value);
 134 
 135   virtual LIR_Opr atomic_xchg_at(LIRAccess& access, LIRItem& value);
 136   virtual LIR_Opr atomic_add_at(LIRAccess& access, LIRItem& value);
 137 
 138   virtual LIR_Opr resolve(LIRGenerator* gen, DecoratorSet decorators, LIR_Opr obj);
 139 
 140   virtual void generate_c1_runtime_stubs(BufferBlob* buffer_blob) {}
 141 };
 142 
 143 #endif // SHARE_GC_SHARED_C1_BARRIERSETC1_HPP