346 bt = T_OBJECT; |
346 bt = T_OBJECT; |
347 type = ftype->make_oopptr(); |
347 type = ftype->make_oopptr(); |
348 } |
348 } |
349 Node* res = NULL; |
349 Node* res = NULL; |
350 if (ac->is_clonebasic()) { |
350 if (ac->is_clonebasic()) { |
|
351 assert(ac->in(ArrayCopyNode::Src) != ac->in(ArrayCopyNode::Dest), "clone source equals destination"); |
351 Node* base = ac->in(ArrayCopyNode::Src)->in(AddPNode::Base); |
352 Node* base = ac->in(ArrayCopyNode::Src)->in(AddPNode::Base); |
352 Node* adr = _igvn.transform(new AddPNode(base, base, MakeConX(offset))); |
353 Node* adr = _igvn.transform(new AddPNode(base, base, MakeConX(offset))); |
353 const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset); |
354 const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset); |
354 res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned); |
355 res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::UnknownControl); |
355 } else { |
356 } else { |
356 if (ac->modifies(offset, offset, &_igvn, true)) { |
357 if (ac->modifies(offset, offset, &_igvn, true)) { |
357 assert(ac->in(ArrayCopyNode::Dest) == alloc->result_cast(), "arraycopy destination should be allocation's result"); |
358 assert(ac->in(ArrayCopyNode::Dest) == alloc->result_cast(), "arraycopy destination should be allocation's result"); |
358 uint shift = exact_log2(type2aelembytes(bt)); |
359 uint shift = exact_log2(type2aelembytes(bt)); |
359 Node* diff = _igvn.transform(new SubINode(ac->in(ArrayCopyNode::SrcPos), ac->in(ArrayCopyNode::DestPos))); |
360 Node* src_pos = ac->in(ArrayCopyNode::SrcPos); |
|
361 Node* dest_pos = ac->in(ArrayCopyNode::DestPos); |
|
362 const TypeInt* src_pos_t = _igvn.type(src_pos)->is_int(); |
|
363 const TypeInt* dest_pos_t = _igvn.type(dest_pos)->is_int(); |
|
364 |
|
365 Node* adr = NULL; |
|
366 const TypePtr* adr_type = NULL; |
|
367 if (src_pos_t->is_con() && dest_pos_t->is_con()) { |
|
368 intptr_t off = ((src_pos_t->get_con() - dest_pos_t->get_con()) << shift) + offset; |
|
369 Node* base = ac->in(ArrayCopyNode::Src); |
|
370 adr = _igvn.transform(new AddPNode(base, base, MakeConX(off))); |
|
371 adr_type = _igvn.type(base)->is_ptr()->add_offset(off); |
|
372 if (ac->in(ArrayCopyNode::Src) == ac->in(ArrayCopyNode::Dest)) { |
|
373 // Don't emit a new load from src if src == dst but try to get the value from memory instead |
|
374 return value_from_mem(ac->in(TypeFunc::Memory), ctl, ft, ftype, adr_type->isa_oopptr(), alloc); |
|
375 } |
|
376 } else { |
|
377 Node* diff = _igvn.transform(new SubINode(ac->in(ArrayCopyNode::SrcPos), ac->in(ArrayCopyNode::DestPos))); |
360 #ifdef _LP64 |
378 #ifdef _LP64 |
361 diff = _igvn.transform(new ConvI2LNode(diff)); |
379 diff = _igvn.transform(new ConvI2LNode(diff)); |
362 #endif |
380 #endif |
363 diff = _igvn.transform(new LShiftXNode(diff, intcon(shift))); |
381 diff = _igvn.transform(new LShiftXNode(diff, intcon(shift))); |
364 |
382 |
365 Node* off = _igvn.transform(new AddXNode(MakeConX(offset), diff)); |
383 Node* off = _igvn.transform(new AddXNode(MakeConX(offset), diff)); |
366 Node* base = ac->in(ArrayCopyNode::Src); |
384 Node* base = ac->in(ArrayCopyNode::Src); |
367 Node* adr = _igvn.transform(new AddPNode(base, base, off)); |
385 adr = _igvn.transform(new AddPNode(base, base, off)); |
368 const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset); |
386 adr_type = _igvn.type(base)->is_ptr()->add_offset(Type::OffsetBot); |
369 res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned); |
387 if (ac->in(ArrayCopyNode::Src) == ac->in(ArrayCopyNode::Dest)) { |
|
388 // Non constant offset in the array: we can't statically |
|
389 // determine the value |
|
390 return NULL; |
|
391 } |
|
392 } |
|
393 res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::UnknownControl); |
370 } |
394 } |
371 } |
395 } |
372 if (res != NULL) { |
396 if (res != NULL) { |
373 res = _igvn.transform(res); |
397 res = _igvn.transform(res); |
374 if (ftype->isa_narrowoop()) { |
398 if (ftype->isa_narrowoop()) { |
785 offset = array_base + j * (intptr_t)element_size; |
808 offset = array_base + j * (intptr_t)element_size; |
786 } |
809 } |
787 |
810 |
788 const Type *field_type; |
811 const Type *field_type; |
789 // The next code is taken from Parse::do_get_xxx(). |
812 // The next code is taken from Parse::do_get_xxx(). |
790 if (basic_elem_type == T_OBJECT || basic_elem_type == T_ARRAY) { |
813 if (is_reference_type(basic_elem_type)) { |
791 if (!elem_type->is_loaded()) { |
814 if (!elem_type->is_loaded()) { |
792 field_type = TypeInstPtr::BOTTOM; |
815 field_type = TypeInstPtr::BOTTOM; |
793 } else if (field != NULL && field->is_static_constant()) { |
816 } else if (field != NULL && field->is_static_constant()) { |
794 // This can happen if the constant oop is non-perm. |
817 // This can happen if the constant oop is non-perm. |
795 ciObject* con = field->constant_value().as_object(); |
818 ciObject* con = field->constant_value().as_object(); |
1006 // Eliminate Initialize node. |
1029 // Eliminate Initialize node. |
1007 InitializeNode *init = use->as_Initialize(); |
1030 InitializeNode *init = use->as_Initialize(); |
1008 assert(init->outcnt() <= 2, "only a control and memory projection expected"); |
1031 assert(init->outcnt() <= 2, "only a control and memory projection expected"); |
1009 Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control); |
1032 Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control); |
1010 if (ctrl_proj != NULL) { |
1033 if (ctrl_proj != NULL) { |
1011 assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection"); |
1034 _igvn.replace_node(ctrl_proj, init->in(TypeFunc::Control)); |
1012 _igvn.replace_node(ctrl_proj, _fallthroughcatchproj); |
1035 #ifdef ASSERT |
|
1036 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); |
|
1037 Node* tmp = init->in(TypeFunc::Control); |
|
1038 while (bs->is_gc_barrier_node(tmp)) { |
|
1039 Node* tmp2 = bs->step_over_gc_barrier_ctrl(tmp); |
|
1040 assert(tmp != tmp2, "Must make progress"); |
|
1041 tmp = tmp2; |
|
1042 } |
|
1043 assert(tmp == _fallthroughcatchproj, "allocation control projection"); |
|
1044 #endif |
1013 } |
1045 } |
1014 Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory); |
1046 Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory); |
1015 if (mem_proj != NULL) { |
1047 if (mem_proj != NULL) { |
1016 Node *mem = init->in(TypeFunc::Memory); |
1048 Node *mem = init->in(TypeFunc::Memory); |
1017 #ifdef ASSERT |
1049 #ifdef ASSERT |
1618 Node* control, Node* rawmem, Node* object, |
1650 Node* control, Node* rawmem, Node* object, |
1619 Node* klass_node, Node* length, |
1651 Node* klass_node, Node* length, |
1620 Node* size_in_bytes) { |
1652 Node* size_in_bytes) { |
1621 InitializeNode* init = alloc->initialization(); |
1653 InitializeNode* init = alloc->initialization(); |
1622 // Store the klass & mark bits |
1654 // Store the klass & mark bits |
1623 Node* mark_node = NULL; |
1655 Node* mark_node = alloc->make_ideal_mark(&_igvn, object, control, rawmem); |
1624 // For now only enable fast locking for non-array types |
1656 if (!mark_node->is_Con()) { |
1625 if (UseBiasedLocking && (length == NULL)) { |
1657 transform_later(mark_node); |
1626 mark_node = make_load(control, rawmem, klass_node, in_bytes(Klass::prototype_header_offset()), TypeRawPtr::BOTTOM, T_ADDRESS); |
1658 } |
1627 } else { |
1659 rawmem = make_store(control, rawmem, object, oopDesc::mark_offset_in_bytes(), mark_node, TypeX_X->basic_type()); |
1628 mark_node = makecon(TypeRawPtr::make((address)markOopDesc::prototype())); |
|
1629 } |
|
1630 rawmem = make_store(control, rawmem, object, oopDesc::mark_offset_in_bytes(), mark_node, T_ADDRESS); |
|
1631 |
1660 |
1632 rawmem = make_store(control, rawmem, object, oopDesc::klass_offset_in_bytes(), klass_node, T_METADATA); |
1661 rawmem = make_store(control, rawmem, object, oopDesc::klass_offset_in_bytes(), klass_node, T_METADATA); |
1633 int header_size = alloc->minimum_header_size(); // conservatively small |
1662 int header_size = alloc->minimum_header_size(); // conservatively small |
1634 |
1663 |
1635 // Array length |
1664 // Array length |
2181 // First, check mark word for the biased lock pattern. |
2210 // First, check mark word for the biased lock pattern. |
2182 Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); |
2211 Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); |
2183 |
2212 |
2184 // Get fast path - mark word has the biased lock pattern. |
2213 // Get fast path - mark word has the biased lock pattern. |
2185 ctrl = opt_bits_test(ctrl, fast_lock_region, 1, mark_node, |
2214 ctrl = opt_bits_test(ctrl, fast_lock_region, 1, mark_node, |
2186 markOopDesc::biased_lock_mask_in_place, |
2215 markWord::biased_lock_mask_in_place, |
2187 markOopDesc::biased_lock_pattern, true); |
2216 markWord::biased_lock_pattern, true); |
2188 // fast_lock_region->in(1) is set to slow path. |
2217 // fast_lock_region->in(1) is set to slow path. |
2189 fast_lock_mem_phi->init_req(1, mem); |
2218 fast_lock_mem_phi->init_req(1, mem); |
2190 |
2219 |
2191 // Now check that the lock is biased to the current thread and has |
2220 // Now check that the lock is biased to the current thread and has |
2192 // the same epoch and bias as Klass::_prototype_header. |
2221 // the same epoch and bias as Klass::_prototype_header. |
2210 Node* cast_thread = transform_later(new CastP2XNode(ctrl, thread)); |
2239 Node* cast_thread = transform_later(new CastP2XNode(ctrl, thread)); |
2211 Node* o_node = transform_later(new OrXNode(cast_thread, proto_node)); |
2240 Node* o_node = transform_later(new OrXNode(cast_thread, proto_node)); |
2212 Node* x_node = transform_later(new XorXNode(o_node, mark_node)); |
2241 Node* x_node = transform_later(new XorXNode(o_node, mark_node)); |
2213 |
2242 |
2214 // Get slow path - mark word does NOT match the value. |
2243 // Get slow path - mark word does NOT match the value. |
|
2244 STATIC_ASSERT(markWord::age_mask_in_place <= INT_MAX); |
2215 Node* not_biased_ctrl = opt_bits_test(ctrl, region, 3, x_node, |
2245 Node* not_biased_ctrl = opt_bits_test(ctrl, region, 3, x_node, |
2216 (~markOopDesc::age_mask_in_place), 0); |
2246 (~(int)markWord::age_mask_in_place), 0); |
2217 // region->in(3) is set to fast path - the object is biased to the current thread. |
2247 // region->in(3) is set to fast path - the object is biased to the current thread. |
2218 mem_phi->init_req(3, mem); |
2248 mem_phi->init_req(3, mem); |
2219 |
2249 |
2220 |
2250 |
2221 // Mark word does NOT match the value (thread | Klass::_prototype_header). |
2251 // Mark word does NOT match the value (thread | Klass::_prototype_header). |
2222 |
2252 |
2223 |
2253 |
2224 // First, check biased pattern. |
2254 // First, check biased pattern. |
2225 // Get fast path - _prototype_header has the same biased lock pattern. |
2255 // Get fast path - _prototype_header has the same biased lock pattern. |
2226 ctrl = opt_bits_test(not_biased_ctrl, fast_lock_region, 2, x_node, |
2256 ctrl = opt_bits_test(not_biased_ctrl, fast_lock_region, 2, x_node, |
2227 markOopDesc::biased_lock_mask_in_place, 0, true); |
2257 markWord::biased_lock_mask_in_place, 0, true); |
2228 |
2258 |
2229 not_biased_ctrl = fast_lock_region->in(2); // Slow path |
2259 not_biased_ctrl = fast_lock_region->in(2); // Slow path |
2230 // fast_lock_region->in(2) - the prototype header is no longer biased |
2260 // fast_lock_region->in(2) - the prototype header is no longer biased |
2231 // and we have to revoke the bias on this object. |
2261 // and we have to revoke the bias on this object. |
2232 // We are going to try to reset the mark of this object to the prototype |
2262 // We are going to try to reset the mark of this object to the prototype |
2244 Node* old_phi = new PhiNode( rebiased_region, TypeX_X); |
2274 Node* old_phi = new PhiNode( rebiased_region, TypeX_X); |
2245 Node* new_phi = new PhiNode( rebiased_region, TypeX_X); |
2275 Node* new_phi = new PhiNode( rebiased_region, TypeX_X); |
2246 |
2276 |
2247 // Get slow path - mark word does NOT match epoch bits. |
2277 // Get slow path - mark word does NOT match epoch bits. |
2248 Node* epoch_ctrl = opt_bits_test(ctrl, rebiased_region, 1, x_node, |
2278 Node* epoch_ctrl = opt_bits_test(ctrl, rebiased_region, 1, x_node, |
2249 markOopDesc::epoch_mask_in_place, 0); |
2279 markWord::epoch_mask_in_place, 0); |
2250 // The epoch of the current bias is not valid, attempt to rebias the object |
2280 // The epoch of the current bias is not valid, attempt to rebias the object |
2251 // toward the current thread. |
2281 // toward the current thread. |
2252 rebiased_region->init_req(2, epoch_ctrl); |
2282 rebiased_region->init_req(2, epoch_ctrl); |
2253 old_phi->init_req(2, mark_node); |
2283 old_phi->init_req(2, mark_node); |
2254 new_phi->init_req(2, o_node); |
2284 new_phi->init_req(2, o_node); |
2255 |
2285 |
2256 // rebiased_region->in(1) is set to fast path. |
2286 // rebiased_region->in(1) is set to fast path. |
2257 // The epoch of the current bias is still valid but we know |
2287 // The epoch of the current bias is still valid but we know |
2258 // nothing about the owner; it might be set or it might be clear. |
2288 // nothing about the owner; it might be set or it might be clear. |
2259 Node* cmask = MakeConX(markOopDesc::biased_lock_mask_in_place | |
2289 Node* cmask = MakeConX(markWord::biased_lock_mask_in_place | |
2260 markOopDesc::age_mask_in_place | |
2290 markWord::age_mask_in_place | |
2261 markOopDesc::epoch_mask_in_place); |
2291 markWord::epoch_mask_in_place); |
2262 Node* old = transform_later(new AndXNode(mark_node, cmask)); |
2292 Node* old = transform_later(new AndXNode(mark_node, cmask)); |
2263 cast_thread = transform_later(new CastP2XNode(ctrl, thread)); |
2293 cast_thread = transform_later(new CastP2XNode(ctrl, thread)); |
2264 Node* new_mark = transform_later(new OrXNode(cast_thread, old)); |
2294 Node* new_mark = transform_later(new OrXNode(cast_thread, old)); |
2265 old_phi->init_req(1, old); |
2295 old_phi->init_req(1, old); |
2266 new_phi->init_req(1, new_mark); |
2296 new_phi->init_req(1, new_mark); |
2371 mem_phi = new PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); |
2401 mem_phi = new PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); |
2372 mem_phi->init_req(3, mem); |
2402 mem_phi->init_req(3, mem); |
2373 |
2403 |
2374 Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); |
2404 Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); |
2375 ctrl = opt_bits_test(ctrl, region, 3, mark_node, |
2405 ctrl = opt_bits_test(ctrl, region, 3, mark_node, |
2376 markOopDesc::biased_lock_mask_in_place, |
2406 markWord::biased_lock_mask_in_place, |
2377 markOopDesc::biased_lock_pattern); |
2407 markWord::biased_lock_pattern); |
2378 } else { |
2408 } else { |
2379 region = new RegionNode(3); |
2409 region = new RegionNode(3); |
2380 // create a Phi for the memory state |
2410 // create a Phi for the memory state |
2381 mem_phi = new PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); |
2411 mem_phi = new PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); |
2382 } |
2412 } |
2561 Node * n = C->macro_node(macro_idx); |
2591 Node * n = C->macro_node(macro_idx); |
2562 assert(n->is_macro(), "only macro nodes expected here"); |
2592 assert(n->is_macro(), "only macro nodes expected here"); |
2563 if (_igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) { |
2593 if (_igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) { |
2564 // node is unreachable, so don't try to expand it |
2594 // node is unreachable, so don't try to expand it |
2565 C->remove_macro_node(n); |
2595 C->remove_macro_node(n); |
2566 } else if (n->is_ArrayCopy()){ |
2596 continue; |
2567 int macro_count = C->macro_count(); |
2597 } |
|
2598 int macro_count = C->macro_count(); |
|
2599 switch (n->class_id()) { |
|
2600 case Node::Class_Lock: |
|
2601 expand_lock_node(n->as_Lock()); |
|
2602 assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); |
|
2603 break; |
|
2604 case Node::Class_Unlock: |
|
2605 expand_unlock_node(n->as_Unlock()); |
|
2606 assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); |
|
2607 break; |
|
2608 case Node::Class_ArrayCopy: |
2568 expand_arraycopy_node(n->as_ArrayCopy()); |
2609 expand_arraycopy_node(n->as_ArrayCopy()); |
2569 assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); |
2610 assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); |
|
2611 break; |
2570 } |
2612 } |
2571 if (C->failing()) return true; |
2613 if (C->failing()) return true; |
2572 macro_idx --; |
2614 macro_idx --; |
2573 } |
2615 } |
|
2616 |
|
2617 // All nodes except Allocate nodes are expanded now. There could be |
|
2618 // new optimization opportunities (such as folding newly created |
|
2619 // load from a just allocated object). Run IGVN. |
|
2620 _igvn.set_delay_transform(false); |
|
2621 _igvn.optimize(); |
|
2622 if (C->failing()) return true; |
|
2623 |
|
2624 _igvn.set_delay_transform(true); |
2574 |
2625 |
2575 // expand "macro" nodes |
2626 // expand "macro" nodes |
2576 // nodes are removed from the macro list as they are processed |
2627 // nodes are removed from the macro list as they are processed |
2577 while (C->macro_count() > 0) { |
2628 while (C->macro_count() > 0) { |
2578 int macro_count = C->macro_count(); |
2629 int macro_count = C->macro_count(); |