|
39 | 39 | #include "opto/output.hpp" |
40 | 40 | #include "opto/regalloc.hpp" |
41 | 41 | #include "opto/rootnode.hpp" |
| 42 | +#include "opto/runtime.hpp" |
42 | 43 | #include "opto/type.hpp" |
43 | 44 | #include "utilities/growableArray.hpp" |
44 | 45 | #include "utilities/macros.hpp" |
@@ -253,11 +254,51 @@ static const TypeFunc* clone_type() { |
253 | 254 | return TypeFunc::make(domain, range); |
254 | 255 | } |
255 | 256 |
|
| 257 | +#define XTOP LP64_ONLY(COMMA phase->top()) |
| 258 | + |
256 | 259 | void ZBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const { |
257 | 260 | Node* const src = ac->in(ArrayCopyNode::Src); |
| 261 | + |
258 | 262 | if (ac->is_clone_array()) { |
259 | | - // Clone primitive array |
260 | | - BarrierSetC2::clone_at_expansion(phase, ac); |
| 263 | + const TypeAryPtr* ary_ptr = src->get_ptr_type()->isa_aryptr(); |
| 264 | + BasicType bt; |
| 265 | + if (ary_ptr == NULL) { |
| 266 | + // ary_ptr can be null iff we are running with StressReflectiveCode |
| 267 | + // This code will be unreachable |
| 268 | + assert(StressReflectiveCode, "Guard against surprises"); |
| 269 | + bt = T_LONG; |
| 270 | + } else { |
| 271 | + bt = ary_ptr->elem()->array_element_basic_type(); |
| 272 | + if (is_reference_type(bt)) { |
| 273 | + // Clone object array |
| 274 | + bt = T_OBJECT; |
| 275 | + } else { |
| 276 | + // Clone primitive array |
| 277 | + bt = T_LONG; |
| 278 | + } |
| 279 | + } |
| 280 | + |
| 281 | + Node* ctrl = ac->in(TypeFunc::Control); |
| 282 | + Node* mem = ac->in(TypeFunc::Memory); |
| 283 | + Node* src = ac->in(ArrayCopyNode::Src); |
| 284 | + Node* src_offset = ac->in(ArrayCopyNode::SrcPos); |
| 285 | + Node* dest = ac->in(ArrayCopyNode::Dest); |
| 286 | + Node* dest_offset = ac->in(ArrayCopyNode::DestPos); |
| 287 | + Node* length = ac->in(ArrayCopyNode::Length); |
| 288 | + |
| 289 | + Node* payload_src = phase->basic_plus_adr(src, src_offset); |
| 290 | + Node* payload_dst = phase->basic_plus_adr(dest, dest_offset); |
| 291 | + |
| 292 | + const char* copyfunc_name = "arraycopy"; |
| 293 | + address copyfunc_addr = phase->basictype2arraycopy(bt, NULL, NULL, true, copyfunc_name, true); |
| 294 | + |
| 295 | + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; |
| 296 | + const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type(); |
| 297 | + |
| 298 | + Node* call = phase->make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, payload_src, payload_dst, length XTOP); |
| 299 | + phase->transform_later(call); |
| 300 | + |
| 301 | + phase->igvn().replace_node(ac, call); |
261 | 302 | return; |
262 | 303 | } |
263 | 304 |
|
@@ -289,6 +330,8 @@ void ZBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* a |
289 | 330 | phase->igvn().replace_node(ac, call); |
290 | 331 | } |
291 | 332 |
|
| 333 | +#undef XTOP |
| 334 | + |
292 | 335 | // == Dominating barrier elision == |
293 | 336 |
|
294 | 337 | static bool block_has_safepoint(const Block* block, uint from, uint to) { |
|
0 commit comments