< prev index next >

src/share/vm/opto/graphKit.cpp

Print this page
rev 13055 : Implement barriers for maintaining connection matrix.


  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 #include "precompiled.hpp"
  26 #include "compiler/compileLog.hpp"
  27 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
  28 #include "gc/g1/heapRegion.hpp"
  29 #include "gc/shared/barrierSet.hpp"
  30 #include "gc/shared/cardTableModRefBS.hpp"
  31 #include "gc/shared/collectedHeap.hpp"
  32 #include "gc/shenandoah/brooksPointer.hpp"



  33 #include "memory/resourceArea.hpp"
  34 #include "opto/addnode.hpp"
  35 #include "opto/castnode.hpp"
  36 #include "opto/convertnode.hpp"
  37 #include "opto/graphKit.hpp"
  38 #include "opto/idealKit.hpp"
  39 #include "opto/intrinsicnode.hpp"
  40 #include "opto/locknode.hpp"
  41 #include "opto/machnode.hpp"
  42 #include "opto/opaquenode.hpp"
  43 #include "opto/parse.hpp"
  44 #include "opto/rootnode.hpp"
  45 #include "opto/runtime.hpp"
  46 #include "opto/shenandoahSupport.hpp"
  47 #include "runtime/deoptimization.hpp"
  48 #include "runtime/sharedRuntime.hpp"
  49 
  50 //----------------------------GraphKit-----------------------------------------
  51 // Main utility constructor.
  52 GraphKit::GraphKit(JVMState* jvms)


4126 }
4127 
4128 Node* GraphKit::shenandoah_write_barrier_pre(bool do_load,
4129                                     Node* obj,
4130                                     Node* adr,
4131                                     uint alias_idx,
4132                                     Node* val,
4133                                     const TypeOopPtr* val_type,
4134                                     Node* pre_val,
4135                                     BasicType bt) {
4136 
4137   // Some sanity checks
4138   // Note: val is unused in this routine.
4139 
4140   if (val == NULL) {
4141     g1_write_barrier_pre(do_load, obj, adr, alias_idx, val, val_type, pre_val, bt);
4142     return NULL;
4143   }
4144 
4145   if (! ShenandoahReduceStoreValBarrier) {


4146     g1_write_barrier_pre(do_load, obj, adr, alias_idx, val, val_type, pre_val, bt);
4147     return shenandoah_read_barrier_storeval(val);
4148   }
4149 
4150   if (do_load) {
4151     // We need to generate the load of the previous value
4152     assert(obj != NULL, "must have a base");
4153     assert(adr != NULL, "where are loading from?");
4154     assert(pre_val == NULL, "loaded already?");
4155     assert(val_type != NULL, "need a type");
4156 
4157     if (use_ReduceInitialCardMarks()
4158         && g1_can_remove_pre_barrier(&_gvn, adr, bt, alias_idx)) {
4159       return shenandoah_read_barrier_storeval(val);
4160     }
4161 
4162   } else {
4163     // In this case both val_type and alias_idx are unused.
4164     assert(pre_val != NULL, "must be loaded already");
4165     // Nothing to be done if pre_val is null.
4166     if (pre_val->bottom_type() == TypePtr::NULL_PTR) return val;
4167     assert(pre_val->bottom_type()->basic_type() == T_OBJECT, "or we shouldn't be here");


4244       } __ end_if();  // (!index)
4245     } __ end_if();  // (pre_val != NULL)
4246   } __ end_if();  // (!marking)
4247   Node* new_val = __ value(ival);
4248   // IdealKit generates a Phi with very conservative type, and even
4249   // turns array types into TypeInstPtr (see type.cpp, _const_basic_type[T_ARRAY]).
4250   // We're forcing the result to be the original type.
4251   if (new_val != val) {
4252     const Type* t = _gvn.type(val);
4253     if (new_val->isa_Type()) {
4254       new_val->as_Type()->set_type(t);
4255     }
4256     _gvn.set_type(new_val, t);
4257   }
4258   val = new_val;
4259   __ dead(ival);
4260   // Final sync IdealKit and GraphKit.
4261   final_sync(ideal);
4262   g1_write_barrier_pre_helper(*this, adr);
4263   return val;






















































4264 }
4265 
4266 /*
4267  * G1 similar to any GC with a Young Generation requires a way to keep track of
4268  * references from Old Generation to Young Generation to make sure all live
4269  * objects are found. G1 also requires to keep track of object references
4270  * between different regions to enable evacuation of old regions, which is done
4271  * as part of mixed collections. References are tracked in remembered sets and
4272  * is continuously updated as reference are written to with the help of the
4273  * post-barrier.
4274  *
4275  * To reduce the number of updates to the remembered set the post-barrier
4276  * filters updates to fields in objects located in the Young Generation,
4277  * the same region as the reference, when the NULL is being written or
4278  * if the card is already marked as dirty by an earlier write.
4279  *
4280  * Under certain circumstances it is possible to avoid generating the
4281  * post-barrier completely if it is possible during compile time to prove
4282  * the object is newly allocated and that no safepoint exists between the
4283  * allocation and the store.




  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 #include "precompiled.hpp"
  26 #include "compiler/compileLog.hpp"
  27 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
  28 #include "gc/g1/heapRegion.hpp"
  29 #include "gc/shared/barrierSet.hpp"
  30 #include "gc/shared/cardTableModRefBS.hpp"
  31 #include "gc/shared/collectedHeap.hpp"
  32 #include "gc/shenandoah/brooksPointer.hpp"
  33 #include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
  34 #include "gc/shenandoah/shenandoahHeap.hpp"
  35 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "opto/addnode.hpp"
  38 #include "opto/castnode.hpp"
  39 #include "opto/convertnode.hpp"
  40 #include "opto/graphKit.hpp"
  41 #include "opto/idealKit.hpp"
  42 #include "opto/intrinsicnode.hpp"
  43 #include "opto/locknode.hpp"
  44 #include "opto/machnode.hpp"
  45 #include "opto/opaquenode.hpp"
  46 #include "opto/parse.hpp"
  47 #include "opto/rootnode.hpp"
  48 #include "opto/runtime.hpp"
  49 #include "opto/shenandoahSupport.hpp"
  50 #include "runtime/deoptimization.hpp"
  51 #include "runtime/sharedRuntime.hpp"
  52 
  53 //----------------------------GraphKit-----------------------------------------
  54 // Main utility constructor.
  55 GraphKit::GraphKit(JVMState* jvms)


4129 }
4130 
4131 Node* GraphKit::shenandoah_write_barrier_pre(bool do_load,
4132                                     Node* obj,
4133                                     Node* adr,
4134                                     uint alias_idx,
4135                                     Node* val,
4136                                     const TypeOopPtr* val_type,
4137                                     Node* pre_val,
4138                                     BasicType bt) {
4139 
4140   // Some sanity checks
4141   // Note: val is unused in this routine.
4142 
4143   if (val == NULL) {
4144     g1_write_barrier_pre(do_load, obj, adr, alias_idx, val, val_type, pre_val, bt);
4145     return NULL;
4146   }
4147 
4148   if (! ShenandoahReduceStoreValBarrier) {
4149     val = shenandoah_read_barrier_storeval(val);
4150     shenandoah_update_matrix(adr, val);
4151     g1_write_barrier_pre(do_load, obj, adr, alias_idx, val, val_type, pre_val, bt);
4152     return val;
4153   }
4154 
4155   if (do_load) {
4156     // We need to generate the load of the previous value
4157     assert(obj != NULL, "must have a base");
4158     assert(adr != NULL, "where are loading from?");
4159     assert(pre_val == NULL, "loaded already?");
4160     assert(val_type != NULL, "need a type");
4161 
4162     if (use_ReduceInitialCardMarks()
4163         && g1_can_remove_pre_barrier(&_gvn, adr, bt, alias_idx)) {
4164       return shenandoah_read_barrier_storeval(val);
4165     }
4166 
4167   } else {
4168     // In this case both val_type and alias_idx are unused.
4169     assert(pre_val != NULL, "must be loaded already");
4170     // Nothing to be done if pre_val is null.
4171     if (pre_val->bottom_type() == TypePtr::NULL_PTR) return val;
4172     assert(pre_val->bottom_type()->basic_type() == T_OBJECT, "or we shouldn't be here");


4249       } __ end_if();  // (!index)
4250     } __ end_if();  // (pre_val != NULL)
4251   } __ end_if();  // (!marking)
4252   Node* new_val = __ value(ival);
4253   // IdealKit generates a Phi with very conservative type, and even
4254   // turns array types into TypeInstPtr (see type.cpp, _const_basic_type[T_ARRAY]).
4255   // We're forcing the result to be the original type.
4256   if (new_val != val) {
4257     const Type* t = _gvn.type(val);
4258     if (new_val->isa_Type()) {
4259       new_val->as_Type()->set_type(t);
4260     }
4261     _gvn.set_type(new_val, t);
4262   }
4263   val = new_val;
4264   __ dead(ival);
4265   // Final sync IdealKit and GraphKit.
4266   final_sync(ideal);
4267   g1_write_barrier_pre_helper(*this, adr);
4268   return val;
4269 }
4270 
4271 void GraphKit::shenandoah_update_matrix(Node* adr, Node* val) {
4272   assert(val != NULL, "checked before");
4273   if (adr == NULL) {
4274     return; // Nothing to do
4275   }
4276   assert(adr != NULL, "must not happen");
4277   if (val->bottom_type()->higher_equal(TypePtr::NULL_PTR)) {
4278     // Nothing to do.
4279     return;
4280   }
4281 
4282   ShenandoahConnectionMatrix* matrix = ShenandoahHeap::heap()->connection_matrix();
4283 
4284   enum { _not_null_path = 1, _null_path, PATH_LIMIT };
4285   RegionNode* region = new RegionNode(PATH_LIMIT);
4286   Node* prev_mem = memory(Compile::AliasIdxRaw);
4287   Node* memphi    = PhiNode::make(region, prev_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
4288   Node* null_ctrl = top();
4289   Node* not_null_val = null_check_oop(val, &null_ctrl);
4290 
4291   // Null path: nothing to do.
4292   region->init_req(_null_path, null_ctrl);
4293   memphi->init_req(_null_path, prev_mem);
4294 
4295   // Not null path. Update the matrix.
4296   Node* heapbase = MakeConX((intx) ShenandoahHeap::heap()->first_region_bottom());
4297   Node* region_size_shift = intcon((jint) ShenandoahHeapRegion::RegionSizeShift);
4298   Node* stride = MakeConX((intx) matrix->stride());
4299   Node* matrix_base = makecon(TypeRawPtr::make(matrix->matrix_addr()));
4300   // Compute region index for adr.
4301   Node* adr_idx = _gvn.transform(new CastP2XNode(control(), adr));
4302   adr_idx = _gvn.transform(new SubXNode(adr_idx, heapbase));
4303   adr_idx = _gvn.transform(new URShiftXNode(adr_idx, region_size_shift));
4304   // Compute region index for val.
4305   Node* val_idx = _gvn.transform(new CastP2XNode(control(), not_null_val));
4306   val_idx = _gvn.transform(new SubXNode(val_idx, heapbase));
4307   val_idx = _gvn.transform(new URShiftXNode(val_idx, region_size_shift));
4308   // Compute matrix index & address.
4309   Node* matrix_idx = _gvn.transform(new MulXNode(adr_idx, stride));
4310   matrix_idx = _gvn.transform(new AddXNode(matrix_idx, val_idx));
4311   Node* matrix_adr = basic_plus_adr(top(), matrix_base, matrix_idx);
4312   // Do the store.
4313   const TypePtr* adr_type = TypeRawPtr::BOTTOM;
4314   Node* store = _gvn.transform(StoreNode::make(_gvn, control(), memory(Compile::AliasIdxRaw), matrix_adr, adr_type, intcon(1), T_BOOLEAN, MemNode::unordered));
4315 
4316   region->init_req(_not_null_path, control());
4317   memphi->init_req(_not_null_path, store);
4318 
4319   // Merge control flows and memory.
4320   set_control(_gvn.transform(region));
4321   record_for_igvn(region);
4322   set_memory(_gvn.transform(memphi), Compile::AliasIdxRaw);
4323 }
4324 
4325 /*
4326  * G1 similar to any GC with a Young Generation requires a way to keep track of
4327  * references from Old Generation to Young Generation to make sure all live
4328  * objects are found. G1 also requires to keep track of object references
4329  * between different regions to enable evacuation of old regions, which is done
4330  * as part of mixed collections. References are tracked in remembered sets and
4331  * is continuously updated as reference are written to with the help of the
4332  * post-barrier.
4333  *
4334  * To reduce the number of updates to the remembered set the post-barrier
4335  * filters updates to fields in objects located in the Young Generation,
4336  * the same region as the reference, when the NULL is being written or
4337  * if the card is already marked as dirty by an earlier write.
4338  *
4339  * Under certain circumstances it is possible to avoid generating the
4340  * post-barrier completely if it is possible during compile time to prove
4341  * the object is newly allocated and that no safepoint exists between the
4342  * allocation and the store.


< prev index next >