< prev index next >
src/hotspot/share/opto/arraycopynode.cpp
BarrierSetC2
/*
! * Copyright (c) 2016, 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.
/*
! * Copyright (c) 2016, 2018, 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.
***************
* questions.
*
*/
#include "precompiled.hpp"
+ #include "gc/shared/barrierSet.hpp"
+ #include "gc/shared/c2/barrierSetC2.hpp"
+ #include "gc/shared/c2/cardTableBarrierSetC2.hpp"
#include "opto/arraycopynode.hpp"
#include "opto/graphKit.hpp"
#include "runtime/sharedRuntime.hpp"
+ #include "utilities/macros.hpp"
ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled, bool has_negative_length_guard)
: CallNode(arraycopy_type(), NULL, TypeRawPtr::BOTTOM),
_alloc_tightly_coupled(alloc_tightly_coupled),
_has_negative_length_guard(has_negative_length_guard),
***************
if (src_elem != dest_elem || dest_elem == T_VOID) {
// We don't know if arguments are arrays of the same type
return false;
}
! if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() || !GraphKit::use_ReduceInitialCardMarks())) {
// It's an object array copy but we can't emit the card marking
// that is needed
return false;
}
if (src_elem != dest_elem || dest_elem == T_VOID) {
// We don't know if arguments are arrays of the same type
return false;
}
! BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
! if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() ||
! bs->array_copy_requires_gc_barriers(T_OBJECT))) {
// It's an object array copy but we can't emit the card marking
// that is needed
return false;
}
***************
PhaseIterGVN* igvn = phase->is_IterGVN();
igvn->set_delay_transform(false);
if (is_clonebasic()) {
Node* out_mem = proj_out(TypeFunc::Memory);
if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() ||
out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) {
! assert(!GraphKit::use_ReduceInitialCardMarks(), "can only happen with card marking");
return false;
}
igvn->replace_node(out_mem->raw_out(0), mem);
PhaseIterGVN* igvn = phase->is_IterGVN();
igvn->set_delay_transform(false);
if (is_clonebasic()) {
Node* out_mem = proj_out(TypeFunc::Memory);
+ BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() ||
out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) {
! assert(bs->array_copy_requires_gc_barriers(T_OBJECT), "can only happen with card marking");
return false;
}
igvn->replace_node(out_mem->raw_out(0), mem);
***************
return true;
}
return false;
}
- static Node* step_over_gc_barrier(Node* c) {
- #if INCLUDE_G1GC
- if (UseG1GC && !GraphKit::use_ReduceInitialCardMarks() &&
- c != NULL && c->is_Region() && c->req() == 3) {
- for (uint i = 1; i < c->req(); i++) {
- if (c->in(i) != NULL && c->in(i)->is_Region() &&
- c->in(i)->req() == 3) {
- Node* r = c->in(i);
- for (uint j = 1; j < r->req(); j++) {
- if (r->in(j) != NULL && r->in(j)->is_Proj() &&
- r->in(j)->in(0) != NULL &&
- r->in(j)->in(0)->Opcode() == Op_CallLeaf &&
- r->in(j)->in(0)->as_Call()->entry_point() == CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post)) {
- Node* call = r->in(j)->in(0);
- c = c->in(i == 1 ? 2 : 1);
- if (c != NULL) {
- c = c->in(0);
- if (c != NULL) {
- c = c->in(0);
- assert(call->in(0) == NULL ||
- call->in(0)->in(0) == NULL ||
- call->in(0)->in(0)->in(0) == NULL ||
- call->in(0)->in(0)->in(0)->in(0) == NULL ||
- call->in(0)->in(0)->in(0)->in(0)->in(0) == NULL ||
- c == call->in(0)->in(0)->in(0)->in(0)->in(0), "bad barrier shape");
- return c;
- }
- }
- }
- }
- }
- }
- }
- #endif // INCLUDE_G1GC
- return c;
- }
-
bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase, ArrayCopyNode*& ac) {
Node* c = mb->in(0);
! // step over g1 gc barrier if we're at a clone with ReduceInitialCardMarks off
! c = step_over_gc_barrier(c);
CallNode* call = NULL;
if (c != NULL && c->is_Region()) {
for (uint i = 1; i < c->req(); i++) {
if (c->in(i) != NULL) {
return true;
}
return false;
}
bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase, ArrayCopyNode*& ac) {
Node* c = mb->in(0);
! BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
! // step over g1 gc barrier if we're at e.g. a clone with ReduceInitialCardMarks off
! c = bs->step_over_gc_barrier(c);
CallNode* call = NULL;
if (c != NULL && c->is_Region()) {
for (uint i = 1; i < c->req(); i++) {
if (c->in(i) != NULL) {
***************
}
}
}
} else if (may_modify_helper(t_oop, c->in(0), phase, call)) {
ac = call->isa_ArrayCopy();
! assert(c == mb->in(0) || (ac != NULL && ac->is_clonebasic() && !GraphKit::use_ReduceInitialCardMarks()), "only for clone");
return true;
}
return false;
}
}
}
}
} else if (may_modify_helper(t_oop, c->in(0), phase, call)) {
ac = call->isa_ArrayCopy();
! #ifdef ASSERT
! bool use_ReduceInitialCardMarks = BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) &&
! static_cast<CardTableBarrierSetC2*>(bs)->use_ReduceInitialCardMarks();
! assert(c == mb->in(0) || (ac != NULL && ac->is_clonebasic() && !use_ReduceInitialCardMarks), "only for clone");
! #endif
return true;
}
return false;
}
***************
return true;
}
}
return false;
}
-
< prev index next >