Mercurial > hg > truffle
comparison src/share/vm/opto/escape.cpp @ 7643:3ac7d10a6572
Merge with hsx25/hotspot.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Thu, 31 Jan 2013 15:42:25 +0100 |
parents | b30b3c2a0cf2 |
children | 6f3fd5150b67 |
comparison
equal
deleted
inserted
replaced
7573:17b6a63fe7c2 | 7643:3ac7d10a6572 |
---|---|
521 break; | 521 break; |
522 } | 522 } |
523 case Op_AryEq: | 523 case Op_AryEq: |
524 case Op_StrComp: | 524 case Op_StrComp: |
525 case Op_StrEquals: | 525 case Op_StrEquals: |
526 case Op_StrIndexOf: { | 526 case Op_StrIndexOf: |
527 case Op_EncodeISOArray: { | |
527 add_local_var(n, PointsToNode::ArgEscape); | 528 add_local_var(n, PointsToNode::ArgEscape); |
528 delayed_worklist->push(n); // Process it later. | 529 delayed_worklist->push(n); // Process it later. |
529 break; | 530 break; |
530 } | 531 } |
531 case Op_ThreadLocal: { | 532 case Op_ThreadLocal: { |
699 ELSE_FAIL("Op_StoreP"); | 700 ELSE_FAIL("Op_StoreP"); |
700 } | 701 } |
701 case Op_AryEq: | 702 case Op_AryEq: |
702 case Op_StrComp: | 703 case Op_StrComp: |
703 case Op_StrEquals: | 704 case Op_StrEquals: |
704 case Op_StrIndexOf: { | 705 case Op_StrIndexOf: |
706 case Op_EncodeISOArray: { | |
705 // char[] arrays passed to string intrinsic do not escape but | 707 // char[] arrays passed to string intrinsic do not escape but |
706 // they are not scalar replaceable. Adjust escape state for them. | 708 // they are not scalar replaceable. Adjust escape state for them. |
707 // Start from in(2) edge since in(1) is memory edge. | 709 // Start from in(2) edge since in(1) is memory edge. |
708 for (uint i = 2; i < n->req(); i++) { | 710 for (uint i = 2; i < n->req(); i++) { |
709 Node* adr = n->in(i); | 711 Node* adr = n->in(i); |
2579 // we are looking for. | 2581 // we are looking for. |
2580 break; | 2582 break; |
2581 } | 2583 } |
2582 // Otherwise skip it (the call updated 'result' value). | 2584 // Otherwise skip it (the call updated 'result' value). |
2583 } else if (result->Opcode() == Op_SCMemProj) { | 2585 } else if (result->Opcode() == Op_SCMemProj) { |
2584 assert(result->in(0)->is_LoadStore(), "sanity"); | 2586 Node* mem = result->in(0); |
2585 const Type *at = igvn->type(result->in(0)->in(MemNode::Address)); | 2587 Node* adr = NULL; |
2588 if (mem->is_LoadStore()) { | |
2589 adr = mem->in(MemNode::Address); | |
2590 } else { | |
2591 assert(mem->Opcode() == Op_EncodeISOArray, "sanity"); | |
2592 adr = mem->in(3); // Memory edge corresponds to destination array | |
2593 } | |
2594 const Type *at = igvn->type(adr); | |
2586 if (at != Type::TOP) { | 2595 if (at != Type::TOP) { |
2587 assert (at->isa_ptr() != NULL, "pointer type required."); | 2596 assert (at->isa_ptr() != NULL, "pointer type required."); |
2588 int idx = C->get_alias_index(at->is_ptr()); | 2597 int idx = C->get_alias_index(at->is_ptr()); |
2589 assert(idx != alias_idx, "Object is not scalar replaceable if a LoadStore node access its field"); | 2598 assert(idx != alias_idx, "Object is not scalar replaceable if a LoadStore node access its field"); |
2590 break; | 2599 break; |
2591 } | 2600 } |
2592 result = result->in(0)->in(MemNode::Memory); | 2601 result = mem->in(MemNode::Memory); |
2593 } | 2602 } |
2594 } | 2603 } |
2595 if (result->is_Phi()) { | 2604 if (result->is_Phi()) { |
2596 PhiNode *mphi = result->as_Phi(); | 2605 PhiNode *mphi = result->as_Phi(); |
2597 assert(mphi->bottom_type() == Type::MEMORY, "memory phi required"); | 2606 assert(mphi->bottom_type() == Type::MEMORY, "memory phi required"); |
2925 // (through CheckCastPP nodes) even for debug info. | 2934 // (through CheckCastPP nodes) even for debug info. |
2926 Node* m = use->in(TypeFunc::Memory); | 2935 Node* m = use->in(TypeFunc::Memory); |
2927 if (m->is_MergeMem()) { | 2936 if (m->is_MergeMem()) { |
2928 assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist"); | 2937 assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist"); |
2929 } | 2938 } |
2939 } else if (use->Opcode() == Op_EncodeISOArray) { | |
2940 if (use->in(MemNode::Memory) == n || use->in(3) == n) { | |
2941 // EncodeISOArray overwrites destination array | |
2942 memnode_worklist.append_if_missing(use); | |
2943 } | |
2930 } else { | 2944 } else { |
2931 uint op = use->Opcode(); | 2945 uint op = use->Opcode(); |
2932 if (!(op == Op_CmpP || op == Op_Conv2B || | 2946 if (!(op == Op_CmpP || op == Op_Conv2B || |
2933 op == Op_CastP2X || op == Op_StoreCM || | 2947 op == Op_CastP2X || op == Op_StoreCM || |
2934 op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || | 2948 op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || |
2960 } else if (n->is_MemBar()) { // Initialize, MemBar nodes | 2974 } else if (n->is_MemBar()) { // Initialize, MemBar nodes |
2961 // we don't need to do anything, but the users must be pushed | 2975 // we don't need to do anything, but the users must be pushed |
2962 n = n->as_MemBar()->proj_out(TypeFunc::Memory); | 2976 n = n->as_MemBar()->proj_out(TypeFunc::Memory); |
2963 if (n == NULL) | 2977 if (n == NULL) |
2964 continue; | 2978 continue; |
2979 } else if (n->Opcode() == Op_EncodeISOArray) { | |
2980 // get the memory projection | |
2981 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { | |
2982 Node *use = n->fast_out(i); | |
2983 if (use->Opcode() == Op_SCMemProj) { | |
2984 n = use; | |
2985 break; | |
2986 } | |
2987 } | |
2988 assert(n->Opcode() == Op_SCMemProj, "memory projection required"); | |
2965 } else { | 2989 } else { |
2966 assert(n->is_Mem(), "memory node required."); | 2990 assert(n->is_Mem(), "memory node required."); |
2967 Node *addr = n->in(MemNode::Address); | 2991 Node *addr = n->in(MemNode::Address); |
2968 const Type *addr_t = igvn->type(addr); | 2992 const Type *addr_t = igvn->type(addr); |
2969 if (addr_t == Type::TOP) | 2993 if (addr_t == Type::TOP) |
2997 // push user on appropriate worklist | 3021 // push user on appropriate worklist |
2998 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { | 3022 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { |
2999 Node *use = n->fast_out(i); | 3023 Node *use = n->fast_out(i); |
3000 if (use->is_Phi() || use->is_ClearArray()) { | 3024 if (use->is_Phi() || use->is_ClearArray()) { |
3001 memnode_worklist.append_if_missing(use); | 3025 memnode_worklist.append_if_missing(use); |
3002 } else if(use->is_Mem() && use->in(MemNode::Memory) == n) { | 3026 } else if (use->is_Mem() && use->in(MemNode::Memory) == n) { |
3003 if (use->Opcode() == Op_StoreCM) // Ignore cardmark stores | 3027 if (use->Opcode() == Op_StoreCM) // Ignore cardmark stores |
3004 continue; | 3028 continue; |
3005 memnode_worklist.append_if_missing(use); | 3029 memnode_worklist.append_if_missing(use); |
3006 } else if (use->is_MemBar()) { | 3030 } else if (use->is_MemBar()) { |
3007 memnode_worklist.append_if_missing(use); | 3031 memnode_worklist.append_if_missing(use); |
3008 #ifdef ASSERT | 3032 #ifdef ASSERT |
3009 } else if(use->is_Mem()) { | 3033 } else if(use->is_Mem()) { |
3010 assert(use->in(MemNode::Memory) != n, "EA: missing memory path"); | 3034 assert(use->in(MemNode::Memory) != n, "EA: missing memory path"); |
3011 } else if (use->is_MergeMem()) { | 3035 } else if (use->is_MergeMem()) { |
3012 assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist"); | 3036 assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist"); |
3037 } else if (use->Opcode() == Op_EncodeISOArray) { | |
3038 if (use->in(MemNode::Memory) == n || use->in(3) == n) { | |
3039 // EncodeISOArray overwrites destination array | |
3040 memnode_worklist.append_if_missing(use); | |
3041 } | |
3013 } else { | 3042 } else { |
3014 uint op = use->Opcode(); | 3043 uint op = use->Opcode(); |
3015 if (!(op == Op_StoreCM || | 3044 if (!(op == Op_StoreCM || |
3016 (op == Op_CallLeaf && use->as_CallLeaf()->_name != NULL && | 3045 (op == Op_CallLeaf && use->as_CallLeaf()->_name != NULL && |
3017 strcmp(use->as_CallLeaf()->_name, "g1_wb_pre") == 0) || | 3046 strcmp(use->as_CallLeaf()->_name, "g1_wb_pre") == 0) || |