91 st->print(", idx=Bot;");
92 else if (atp->index() == Compile::AliasIdxTop)
93 st->print(", idx=Top;");
94 else if (atp->index() == Compile::AliasIdxRaw)
95 st->print(", idx=Raw;");
96 else {
97 ciField* field = atp->field();
98 if (field) {
99 st->print(", name=");
100 field->print_name_on(st);
101 }
102 st->print(", idx=%d;", atp->index());
103 }
104 }
105 }
106
107 extern void print_alias_types();
108
109 #endif
110
111 static bool membar_for_arraycopy_helper(const TypeOopPtr *t_oop, MergeMemNode* mm, PhaseTransform *phase) {
112 if (mm->memory_at(Compile::AliasIdxRaw)->is_Proj()) {
113 Node* n = mm->memory_at(Compile::AliasIdxRaw)->in(0);
114 if ((n->is_ArrayCopy() && n->as_ArrayCopy()->may_modify(t_oop, phase)) ||
115 (n->is_CallLeaf() && n->as_CallLeaf()->may_modify(t_oop, phase))) {
116 return true;
117 }
118 }
119 return false;
120 }
121
122 static bool membar_for_arraycopy(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase) {
123 Node* mem = mb->in(TypeFunc::Memory);
124 if (mem->is_MergeMem()) {
125 return membar_for_arraycopy_helper(t_oop, mem->as_MergeMem(), phase);
126 } else if (mem->is_Phi()) {
127 // after macro expansion of an ArrayCopyNode we may have a Phi
128 for (uint i = 1; i < mem->req(); i++) {
129 if (mem->in(i) != NULL && mem->in(i)->is_MergeMem() && membar_for_arraycopy_helper(t_oop, mem->in(i)->as_MergeMem(), phase)) {
130 return true;
131 }
132 }
133 }
134 return false;
135 }
136
137 Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase) {
138 assert((t_oop != NULL), "sanity");
139 bool is_instance = t_oop->is_known_instance_field();
140 bool is_boxed_value_load = t_oop->is_ptr_to_boxed_value() &&
141 (load != NULL) && load->is_Load() &&
142 (phase->is_IterGVN() != NULL);
143 if (!(is_instance || is_boxed_value_load))
144 return mchain; // don't try to optimize non-instance types
145 uint instance_id = t_oop->instance_id();
146 Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory);
147 Node *prev = NULL;
148 Node *result = mchain;
149 while (prev != result) {
150 prev = result;
151 if (result == start_mem)
152 break; // hit one of our sentinels
153 // skip over a call which does not affect this memory slice
|
91 st->print(", idx=Bot;");
92 else if (atp->index() == Compile::AliasIdxTop)
93 st->print(", idx=Top;");
94 else if (atp->index() == Compile::AliasIdxRaw)
95 st->print(", idx=Raw;");
96 else {
97 ciField* field = atp->field();
98 if (field) {
99 st->print(", name=");
100 field->print_name_on(st);
101 }
102 st->print(", idx=%d;", atp->index());
103 }
104 }
105 }
106
107 extern void print_alias_types();
108
109 #endif
110
111 static bool membar_for_arraycopy_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase) {
112 if (n->is_Proj()) {
113 n = n->in(0);
114 if (n->is_Call() && n->as_Call()->may_modify(t_oop, phase)) {
115 return true;
116 }
117 }
118 return false;
119 }
120
121 static bool membar_for_arraycopy(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase) {
122 Node* mem = mb->in(TypeFunc::Memory);
123
124 if (mem->is_MergeMem()) {
125 Node* n = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
126 if (membar_for_arraycopy_helper(t_oop, n, phase)) {
127 return true;
128 } else if (n->is_Phi()) {
129 for (uint i = 1; i < n->req(); i++) {
130 if (n->in(i) != NULL) {
131 if (membar_for_arraycopy_helper(t_oop, n->in(i), phase)) {
132 return true;
133 }
134 }
135 }
136 }
137 }
138
139 return false;
140 }
141
142 Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oop, Node *load, PhaseGVN *phase) {
143 assert((t_oop != NULL), "sanity");
144 bool is_instance = t_oop->is_known_instance_field();
145 bool is_boxed_value_load = t_oop->is_ptr_to_boxed_value() &&
146 (load != NULL) && load->is_Load() &&
147 (phase->is_IterGVN() != NULL);
148 if (!(is_instance || is_boxed_value_load))
149 return mchain; // don't try to optimize non-instance types
150 uint instance_id = t_oop->instance_id();
151 Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory);
152 Node *prev = NULL;
153 Node *result = mchain;
154 while (prev != result) {
155 prev = result;
156 if (result == start_mem)
157 break; // hit one of our sentinels
158 // skip over a call which does not affect this memory slice
|