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