annotate src/share/vm/opto/memnode.cpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents 4311f23817fd
children 02f0a9b6f654
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1100
diff changeset
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1100
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1100
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1100
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // Portions of code courtesy of Clifford Click
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // Optimization - Graph Style
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
30 #include "incls/_memnode.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
31
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
32 static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const TypePtr *tp, const TypePtr *adr_check, outputStream *st);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
33
0
a61af66fc99e Initial load
duke
parents:
diff changeset
34 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
35 uint MemNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 const TypePtr *MemNode::adr_type() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
38 Node* adr = in(Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
39 const TypePtr* cross_check = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 DEBUG_ONLY(cross_check = _adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
41 return calculate_adr_type(adr->bottom_type(), cross_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
42 }
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
45 void MemNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 if (in(Address) == NULL) return; // node is dead
a61af66fc99e Initial load
duke
parents:
diff changeset
47 #ifndef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // fake the missing field
a61af66fc99e Initial load
duke
parents:
diff changeset
49 const TypePtr* _adr_type = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 if (in(Address) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _adr_type = in(Address)->bottom_type()->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
52 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
53 dump_adr_type(this, _adr_type, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
56 if( C->alias_type(_adr_type)->is_volatile() )
a61af66fc99e Initial load
duke
parents:
diff changeset
57 st->print(" Volatile!");
a61af66fc99e Initial load
duke
parents:
diff changeset
58 }
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 void MemNode::dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 st->print(" @");
a61af66fc99e Initial load
duke
parents:
diff changeset
62 if (adr_type == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
63 st->print("NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
64 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 adr_type->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
66 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
67 Compile::AliasType* atp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 if (C->have_alias_type(adr_type)) atp = C->alias_type(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
69 if (atp == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
70 st->print(", idx=?\?;");
a61af66fc99e Initial load
duke
parents:
diff changeset
71 else if (atp->index() == Compile::AliasIdxBot)
a61af66fc99e Initial load
duke
parents:
diff changeset
72 st->print(", idx=Bot;");
a61af66fc99e Initial load
duke
parents:
diff changeset
73 else if (atp->index() == Compile::AliasIdxTop)
a61af66fc99e Initial load
duke
parents:
diff changeset
74 st->print(", idx=Top;");
a61af66fc99e Initial load
duke
parents:
diff changeset
75 else if (atp->index() == Compile::AliasIdxRaw)
a61af66fc99e Initial load
duke
parents:
diff changeset
76 st->print(", idx=Raw;");
a61af66fc99e Initial load
duke
parents:
diff changeset
77 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 ciField* field = atp->field();
a61af66fc99e Initial load
duke
parents:
diff changeset
79 if (field) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 st->print(", name=");
a61af66fc99e Initial load
duke
parents:
diff changeset
81 field->print_name_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83 st->print(", idx=%d;", atp->index());
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 extern void print_alias_types();
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
91
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
92 Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
93 const TypeOopPtr *tinst = t_adr->isa_oopptr();
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
94 if (tinst == NULL || !tinst->is_known_instance_field())
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
95 return mchain; // don't try to optimize non-instance types
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
96 uint instance_id = tinst->instance_id();
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 247
diff changeset
97 Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory);
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
98 Node *prev = NULL;
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
99 Node *result = mchain;
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
100 while (prev != result) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
101 prev = result;
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 247
diff changeset
102 if (result == start_mem)
605
98cb887364d3 6810672: Comment typos
twisti
parents: 583
diff changeset
103 break; // hit one of our sentinels
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
104 // skip over a call which does not affect this memory slice
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
105 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
106 Node *proj_in = result->in(0);
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 247
diff changeset
107 if (proj_in->is_Allocate() && proj_in->_idx == instance_id) {
605
98cb887364d3 6810672: Comment typos
twisti
parents: 583
diff changeset
108 break; // hit one of our sentinels
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 247
diff changeset
109 } else if (proj_in->is_Call()) {
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
110 CallNode *call = proj_in->as_Call();
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
111 if (!call->may_modify(t_adr, phase)) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
112 result = call->in(TypeFunc::Memory);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
113 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
114 } else if (proj_in->is_Initialize()) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
115 AllocateNode* alloc = proj_in->as_Initialize()->allocation();
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
116 // Stop if this is the initialization for the object instance which
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
117 // which contains this memory slice, otherwise skip over it.
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
118 if (alloc != NULL && alloc->_idx != instance_id) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
119 result = proj_in->in(TypeFunc::Memory);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
120 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
121 } else if (proj_in->is_MemBar()) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
122 result = proj_in->in(TypeFunc::Memory);
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 247
diff changeset
123 } else {
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 247
diff changeset
124 assert(false, "unexpected projection");
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
125 }
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
126 } else if (result->is_ClearArray()) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
127 if (!ClearArrayNode::step_through(&result, instance_id, phase)) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
128 // Can not bypass initialization of the instance
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
129 // we are looking for.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
130 break;
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
131 }
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
132 // Otherwise skip it (the call updated 'result' value).
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
133 } else if (result->is_MergeMem()) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
134 result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
135 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
136 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
137 return result;
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
138 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
139
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
140 Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
141 const TypeOopPtr *t_oop = t_adr->isa_oopptr();
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
142 bool is_instance = (t_oop != NULL) && t_oop->is_known_instance_field();
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
143 PhaseIterGVN *igvn = phase->is_IterGVN();
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
144 Node *result = mchain;
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
145 result = optimize_simple_memory_chain(result, t_adr, phase);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
146 if (is_instance && igvn != NULL && result->is_Phi()) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
147 PhiNode *mphi = result->as_Phi();
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
148 assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
149 const TypePtr *t = mphi->adr_type();
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
150 if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
151 t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
247
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
152 t->is_oopptr()->cast_to_exactness(true)
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
153 ->is_oopptr()->cast_to_ptr_type(t_oop->ptr())
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
154 ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) {
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
155 // clone the Phi with our address type
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
156 result = mphi->split_out_instance(t_adr, igvn);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
157 } else {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
158 assert(phase->C->get_alias_index(t) == phase->C->get_alias_index(t_adr), "correct memory chain");
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
159 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
160 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
161 return result;
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
162 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
163
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
164 static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const TypePtr *tp, const TypePtr *adr_check, outputStream *st) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
165 uint alias_idx = phase->C->get_alias_index(tp);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
166 Node *mem = mmem;
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
167 #ifdef ASSERT
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
168 {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
169 // Check that current type is consistent with the alias index used during graph construction
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
170 assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx");
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
171 bool consistent = adr_check == NULL || adr_check->empty() ||
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
172 phase->C->must_alias(adr_check, alias_idx );
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
173 // Sometimes dead array references collapse to a[-1], a[-2], or a[-3]
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
174 if( !consistent && adr_check != NULL && !adr_check->empty() &&
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
175 tp->isa_aryptr() && tp->offset() == Type::OffsetBot &&
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
176 adr_check->isa_aryptr() && adr_check->offset() != Type::OffsetBot &&
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
177 ( adr_check->offset() == arrayOopDesc::length_offset_in_bytes() ||
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
178 adr_check->offset() == oopDesc::klass_offset_in_bytes() ||
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
179 adr_check->offset() == oopDesc::mark_offset_in_bytes() ) ) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
180 // don't assert if it is dead code.
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
181 consistent = true;
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
182 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
183 if( !consistent ) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
184 st->print("alias_idx==%d, adr_check==", alias_idx);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
185 if( adr_check == NULL ) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
186 st->print("NULL");
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
187 } else {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
188 adr_check->dump();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
189 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
190 st->cr();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
191 print_alias_types();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
192 assert(consistent, "adr_check must match alias idx");
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
193 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
194 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
195 #endif
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
196 // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
197 // means an array I have not precisely typed yet. Do not do any
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
198 // alias stuff with it any time soon.
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
199 const TypeOopPtr *tinst = tp->isa_oopptr();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
200 if( tp->base() != Type::AnyPtr &&
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
201 !(tinst &&
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
202 tinst->klass()->is_java_lang_Object() &&
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
203 tinst->offset() == Type::OffsetBot) ) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
204 // compress paths and change unreachable cycles to TOP
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
205 // If not, we can update the input infinitely along a MergeMem cycle
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
206 // Equivalent code in PhiNode::Ideal
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
207 Node* m = phase->transform(mmem);
605
98cb887364d3 6810672: Comment typos
twisti
parents: 583
diff changeset
208 // If transformed to a MergeMem, get the desired slice
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
209 // Otherwise the returned node represents memory for every slice
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
210 mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m;
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
211 // Update input if it is progress over what we have now
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
212 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
213 return mem;
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
214 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
215
0
a61af66fc99e Initial load
duke
parents:
diff changeset
216 //--------------------------Ideal_common---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Look for degenerate control and memory inputs. Bypass MergeMem inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Unhook non-raw memories from complete (macro-expanded) initializations.
a61af66fc99e Initial load
duke
parents:
diff changeset
219 Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // If our control input is a dead region, kill all below the region
a61af66fc99e Initial load
duke
parents:
diff changeset
221 Node *ctl = in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 if (ctl && remove_dead_region(phase, can_reshape))
a61af66fc99e Initial load
duke
parents:
diff changeset
223 return this;
305
ab075d07f1ba 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 293
diff changeset
224 ctl = in(MemNode::Control);
ab075d07f1ba 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 293
diff changeset
225 // Don't bother trying to transform a dead node
ab075d07f1ba 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 293
diff changeset
226 if( ctl && ctl->is_top() ) return NodeSentinel;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227
708
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
228 PhaseIterGVN *igvn = phase->is_IterGVN();
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
229 // Wait if control on the worklist.
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
230 if (ctl && can_reshape && igvn != NULL) {
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
231 Node* bol = NULL;
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
232 Node* cmp = NULL;
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
233 if (ctl->in(0)->is_If()) {
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
234 assert(ctl->is_IfTrue() || ctl->is_IfFalse(), "sanity");
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
235 bol = ctl->in(0)->in(1);
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
236 if (bol->is_Bool())
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
237 cmp = ctl->in(0)->in(1)->in(1);
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
238 }
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
239 if (igvn->_worklist.member(ctl) ||
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
240 (bol != NULL && igvn->_worklist.member(bol)) ||
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
241 (cmp != NULL && igvn->_worklist.member(cmp)) ) {
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
242 // This control path may be dead.
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
243 // Delay this memory node transformation until the control is processed.
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
244 phase->is_IterGVN()->_worklist.push(this);
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
245 return NodeSentinel; // caller will return NULL
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
246 }
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
247 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // Ignore if memory is dead, or self-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
249 Node *mem = in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
250 if( phase->type( mem ) == Type::TOP ) return NodeSentinel; // caller will return NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
251 assert( mem != this, "dead loop in MemNode::Ideal" );
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 Node *address = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
254 const Type *t_adr = phase->type( address );
a61af66fc99e Initial load
duke
parents:
diff changeset
255 if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
256
708
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
257 if( can_reshape && igvn != NULL &&
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
258 (igvn->_worklist.member(address) || phase->type(address) != adr_type()) ) {
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 366
diff changeset
259 // The address's base and type may change when the address is processed.
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 366
diff changeset
260 // Delay this mem node transformation until the address is processed.
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 366
diff changeset
261 phase->is_IterGVN()->_worklist.push(this);
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 366
diff changeset
262 return NodeSentinel; // caller will return NULL
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 366
diff changeset
263 }
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 366
diff changeset
264
1062
dcdcc8c16e20 6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents: 986
diff changeset
265 // Do NOT remove or optimize the next lines: ensure a new alias index
dcdcc8c16e20 6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents: 986
diff changeset
266 // is allocated for an oop pointer type before Escape Analysis.
dcdcc8c16e20 6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents: 986
diff changeset
267 // Note: C++ will not remove it since the call has side effect.
dcdcc8c16e20 6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents: 986
diff changeset
268 if ( t_adr->isa_oopptr() ) {
dcdcc8c16e20 6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents: 986
diff changeset
269 int alias_idx = phase->C->get_alias_index(t_adr->is_ptr());
dcdcc8c16e20 6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents: 986
diff changeset
270 }
dcdcc8c16e20 6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents: 986
diff changeset
271
708
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
272 #ifdef ASSERT
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
273 Node* base = NULL;
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
274 if (address->is_AddP())
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
275 base = address->in(AddPNode::Base);
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
276 assert(base == NULL || t_adr->isa_rawptr() ||
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
277 !phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?");
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
278 #endif
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
279
0
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // Avoid independent memory operations
a61af66fc99e Initial load
duke
parents:
diff changeset
281 Node* old_mem = mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
282
36
f34d9da7acb2 6667618: disable LoadL->ConvL2I ==> LoadI optimization
kvn
parents: 29
diff changeset
283 // The code which unhooks non-raw memories from complete (macro-expanded)
f34d9da7acb2 6667618: disable LoadL->ConvL2I ==> LoadI optimization
kvn
parents: 29
diff changeset
284 // initializations was removed. After macro-expansion all stores catched
f34d9da7acb2 6667618: disable LoadL->ConvL2I ==> LoadI optimization
kvn
parents: 29
diff changeset
285 // by Initialize node became raw stores and there is no information
f34d9da7acb2 6667618: disable LoadL->ConvL2I ==> LoadI optimization
kvn
parents: 29
diff changeset
286 // which memory slices they modify. So it is unsafe to move any memory
f34d9da7acb2 6667618: disable LoadL->ConvL2I ==> LoadI optimization
kvn
parents: 29
diff changeset
287 // operation above these stores. Also in most cases hooked non-raw memories
f34d9da7acb2 6667618: disable LoadL->ConvL2I ==> LoadI optimization
kvn
parents: 29
diff changeset
288 // were already unhooked by using information from detect_ptr_independence()
f34d9da7acb2 6667618: disable LoadL->ConvL2I ==> LoadI optimization
kvn
parents: 29
diff changeset
289 // and find_previous_store().
0
a61af66fc99e Initial load
duke
parents:
diff changeset
290
a61af66fc99e Initial load
duke
parents:
diff changeset
291 if (mem->is_MergeMem()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 MergeMemNode* mmem = mem->as_MergeMem();
a61af66fc99e Initial load
duke
parents:
diff changeset
293 const TypePtr *tp = t_adr->is_ptr();
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
294
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
295 mem = step_through_mergemem(phase, mmem, tp, adr_type(), tty);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 if (mem != old_mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 set_req(MemNode::Memory, mem);
305
ab075d07f1ba 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 293
diff changeset
300 if (phase->type( mem ) == Type::TOP) return NodeSentinel;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
301 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
303
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // let the subclass continue analyzing...
a61af66fc99e Initial load
duke
parents:
diff changeset
305 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Helper function for proving some simple control dominations.
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
309 // Attempt to prove that all control inputs of 'dom' dominate 'sub'.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // Already assumes that 'dom' is available at 'sub', and that 'sub'
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // is not a constant (dominated by the method's StartNode).
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Used by MemNode::find_previous_store to prove that the
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // control input of a memory operation predates (dominates)
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // an allocation it wants to look past.
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
315 bool MemNode::all_controls_dominate(Node* dom, Node* sub) {
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
316 if (dom == NULL || dom->is_top() || sub == NULL || sub->is_top())
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
317 return false; // Conservative answer for dead code
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
318
193
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
319 // Check 'dom'. Skip Proj and CatchProj nodes.
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
320 dom = dom->find_exact_control(dom);
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
321 if (dom == NULL || dom->is_top())
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
322 return false; // Conservative answer for dead code
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
323
193
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
324 if (dom == sub) {
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
325 // For the case when, for example, 'sub' is Initialize and the original
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
326 // 'dom' is Proj node of the 'sub'.
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
327 return false;
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
328 }
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
329
155
723be81c1212 6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents: 128
diff changeset
330 if (dom->is_Con() || dom->is_Start() || dom->is_Root() || dom == sub)
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
331 return true;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
332
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
333 // 'dom' dominates 'sub' if its control edge and control edges
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
334 // of all its inputs dominate or equal to sub's control edge.
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
335
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
336 // Currently 'sub' is either Allocate, Initialize or Start nodes.
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
337 // Or Region for the check in LoadNode::Ideal();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
338 // 'sub' should have sub->in(0) != NULL.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
339 assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start() ||
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
340 sub->is_Region(), "expecting only these nodes");
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
341
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
342 // Get control edge of 'sub'.
193
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
343 Node* orig_sub = sub;
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
344 sub = sub->find_exact_control(sub->in(0));
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
345 if (sub == NULL || sub->is_top())
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
346 return false; // Conservative answer for dead code
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
347
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
348 assert(sub->is_CFG(), "expecting control");
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
349
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
350 if (sub == dom)
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
351 return true;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
352
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
353 if (sub->is_Start() || sub->is_Root())
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
354 return false;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
355
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
356 {
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
357 // Check all control edges of 'dom'.
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
358
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
359 ResourceMark rm;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
360 Arena* arena = Thread::current()->resource_area();
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
361 Node_List nlist(arena);
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
362 Unique_Node_List dom_list(arena);
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
363
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
364 dom_list.push(dom);
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
365 bool only_dominating_controls = false;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
366
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
367 for (uint next = 0; next < dom_list.size(); next++) {
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
368 Node* n = dom_list.at(next);
193
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
369 if (n == orig_sub)
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
370 return false; // One of dom's inputs dominated by sub.
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
371 if (!n->is_CFG() && n->pinned()) {
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
372 // Check only own control edge for pinned non-control nodes.
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
373 n = n->find_exact_control(n->in(0));
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
374 if (n == NULL || n->is_top())
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
375 return false; // Conservative answer for dead code
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
376 assert(n->is_CFG(), "expecting control");
193
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
377 dom_list.push(n);
44a553b2809d 6714406: Node::dominates() does not always check for TOP
kvn
parents: 169
diff changeset
378 } else if (n->is_Con() || n->is_Start() || n->is_Root()) {
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
379 only_dominating_controls = true;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
380 } else if (n->is_CFG()) {
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
381 if (n->dominates(sub, nlist))
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
382 only_dominating_controls = true;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
383 else
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
384 return false;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
385 } else {
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
386 // First, own control edge.
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
387 Node* m = n->find_exact_control(n->in(0));
155
723be81c1212 6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents: 128
diff changeset
388 if (m != NULL) {
723be81c1212 6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents: 128
diff changeset
389 if (m->is_top())
723be81c1212 6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents: 128
diff changeset
390 return false; // Conservative answer for dead code
723be81c1212 6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents: 128
diff changeset
391 dom_list.push(m);
723be81c1212 6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents: 128
diff changeset
392 }
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
393 // Now, the rest of edges.
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
394 uint cnt = n->req();
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
395 for (uint i = 1; i < cnt; i++) {
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
396 m = n->find_exact_control(n->in(i));
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
397 if (m == NULL || m->is_top())
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
398 continue;
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
399 dom_list.push(m);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
402 }
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
403 return only_dominating_controls;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 //---------------------detect_ptr_independence---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // Used by MemNode::find_previous_store to prove that two base
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // pointers are never equal.
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // The pointers are accompanied by their associated allocations,
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // if any, which have been previously discovered by the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
412 bool MemNode::detect_ptr_independence(Node* p1, AllocateNode* a1,
a61af66fc99e Initial load
duke
parents:
diff changeset
413 Node* p2, AllocateNode* a2,
a61af66fc99e Initial load
duke
parents:
diff changeset
414 PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // Attempt to prove that these two pointers cannot be aliased.
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // They may both manifestly be allocations, and they should differ.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // Or, if they are not both allocations, they can be distinct constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Otherwise, one is an allocation and the other a pre-existing value.
a61af66fc99e Initial load
duke
parents:
diff changeset
419 if (a1 == NULL && a2 == NULL) { // neither an allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
420 return (p1 != p2) && p1->is_Con() && p2->is_Con();
a61af66fc99e Initial load
duke
parents:
diff changeset
421 } else if (a1 != NULL && a2 != NULL) { // both allocations
a61af66fc99e Initial load
duke
parents:
diff changeset
422 return (a1 != a2);
a61af66fc99e Initial load
duke
parents:
diff changeset
423 } else if (a1 != NULL) { // one allocation a1
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.)
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
425 return all_controls_dominate(p2, a1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
426 } else { //(a2 != NULL) // one allocation a2
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
427 return all_controls_dominate(p1, a2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // The logic for reordering loads and stores uses four steps:
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // (a) Walk carefully past stores and initializations which we
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // can prove are independent of this load.
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // (b) Observe that the next memory state makes an exact match
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // with self (load or store), and locate the relevant store.
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // (c) Ensure that, if we were to wire self directly to the store,
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // the optimizer would fold it up somehow.
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // (d) Do the rewiring, and return, depending on some other part of
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // the optimizer to fold up the load.
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // This routine handles steps (a) and (b). Steps (c) and (d) are
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // specific to loads and stores, so they are handled by the callers.
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // (Currently, only LoadNode::Ideal has steps (c), (d). More later.)
a61af66fc99e Initial load
duke
parents:
diff changeset
445 //
a61af66fc99e Initial load
duke
parents:
diff changeset
446 Node* MemNode::find_previous_store(PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 Node* ctrl = in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
448 Node* adr = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 intptr_t offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
450 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
451 AllocateNode* alloc = AllocateNode::Ideal_allocation(base, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
452
a61af66fc99e Initial load
duke
parents:
diff changeset
453 if (offset == Type::OffsetBot)
a61af66fc99e Initial load
duke
parents:
diff changeset
454 return NULL; // cannot unalias unless there are precise offsets
a61af66fc99e Initial load
duke
parents:
diff changeset
455
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
456 const TypeOopPtr *addr_t = adr->bottom_type()->isa_oopptr();
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
457
0
a61af66fc99e Initial load
duke
parents:
diff changeset
458 intptr_t size_in_bytes = memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 Node* mem = in(MemNode::Memory); // start searching here...
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 int cnt = 50; // Cycle limiter
a61af66fc99e Initial load
duke
parents:
diff changeset
463 for (;;) { // While we can dance past unrelated stores...
a61af66fc99e Initial load
duke
parents:
diff changeset
464 if (--cnt < 0) break; // Caught in cycle or a complicated dance?
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 if (mem->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 Node* st_adr = mem->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
468 intptr_t st_offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 Node* st_base = AddPNode::Ideal_base_and_offset(st_adr, phase, st_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
470 if (st_base == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
471 break; // inscrutable pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
472 if (st_offset != offset && st_offset != Type::OffsetBot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473 const int MAX_STORE = BytesPerLong;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 if (st_offset >= offset + size_in_bytes ||
a61af66fc99e Initial load
duke
parents:
diff changeset
475 st_offset <= offset - MAX_STORE ||
a61af66fc99e Initial load
duke
parents:
diff changeset
476 st_offset <= offset - mem->as_Store()->memory_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // Success: The offsets are provably independent.
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // (You may ask, why not just test st_offset != offset and be done?
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // The answer is that stores of different sizes can co-exist
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // in the same sequence of RawMem effects. We sometimes initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // a whole 'tile' of array elements with a single jint or jlong.)
a61af66fc99e Initial load
duke
parents:
diff changeset
482 mem = mem->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
483 continue; // (a) advance through independent store memory
a61af66fc99e Initial load
duke
parents:
diff changeset
484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 if (st_base != base &&
a61af66fc99e Initial load
duke
parents:
diff changeset
487 detect_ptr_independence(base, alloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
488 st_base,
a61af66fc99e Initial load
duke
parents:
diff changeset
489 AllocateNode::Ideal_allocation(st_base, phase),
a61af66fc99e Initial load
duke
parents:
diff changeset
490 phase)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // Success: The bases are provably independent.
a61af66fc99e Initial load
duke
parents:
diff changeset
492 mem = mem->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
493 continue; // (a) advance through independent store memory
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // (b) At this point, if the bases or offsets do not agree, we lose,
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // since we have not managed to prove 'this' and 'mem' independent.
a61af66fc99e Initial load
duke
parents:
diff changeset
498 if (st_base == base && st_offset == offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 return mem; // let caller handle steps (c), (d)
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 } else if (mem->is_Proj() && mem->in(0)->is_Initialize()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
503 InitializeNode* st_init = mem->in(0)->as_Initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
504 AllocateNode* st_alloc = st_init->allocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if (st_alloc == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
506 break; // something degenerated
a61af66fc99e Initial load
duke
parents:
diff changeset
507 bool known_identical = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
508 bool known_independent = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 if (alloc == st_alloc)
a61af66fc99e Initial load
duke
parents:
diff changeset
510 known_identical = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 else if (alloc != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
512 known_independent = true;
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
513 else if (all_controls_dominate(this, st_alloc))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
514 known_independent = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
515
a61af66fc99e Initial load
duke
parents:
diff changeset
516 if (known_independent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // The bases are provably independent: Either they are
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // manifestly distinct allocations, or else the control
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // of this load dominates the store's allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
520 int alias_idx = phase->C->get_alias_index(adr_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
521 if (alias_idx == Compile::AliasIdxRaw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
522 mem = st_alloc->in(TypeFunc::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
523 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 mem = st_init->memory(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
526 continue; // (a) advance through independent store memory
a61af66fc99e Initial load
duke
parents:
diff changeset
527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // (b) at this point, if we are not looking at a store initializing
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // the same allocation we are loading from, we lose.
a61af66fc99e Initial load
duke
parents:
diff changeset
531 if (known_identical) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // From caller, can_see_stored_value will consult find_captured_store.
a61af66fc99e Initial load
duke
parents:
diff changeset
533 return mem; // let caller handle steps (c), (d)
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
536 } else if (addr_t != NULL && addr_t->is_known_instance_field()) {
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
537 // Can't use optimize_simple_memory_chain() since it needs PhaseGVN.
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
538 if (mem->is_Proj() && mem->in(0)->is_Call()) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
539 CallNode *call = mem->in(0)->as_Call();
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
540 if (!call->may_modify(addr_t, phase)) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
541 mem = call->in(TypeFunc::Memory);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
542 continue; // (a) advance through independent call memory
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
543 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
544 } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
545 mem = mem->in(0)->in(TypeFunc::Memory);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
546 continue; // (a) advance through independent MemBar memory
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
547 } else if (mem->is_ClearArray()) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
548 if (ClearArrayNode::step_through(&mem, (uint)addr_t->instance_id(), phase)) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
549 // (the call updated 'mem' value)
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
550 continue; // (a) advance through independent allocation memory
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
551 } else {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
552 // Can not bypass initialization of the instance
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
553 // we are looking for.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
554 return mem;
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
555 }
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
556 } else if (mem->is_MergeMem()) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
557 int alias_idx = phase->C->get_alias_index(adr_type());
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
558 mem = mem->as_MergeMem()->memory_at(alias_idx);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
559 continue; // (a) advance through independent MergeMem memory
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
560 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
561 }
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // Unless there is an explicit 'continue', we must bail out here,
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // because 'mem' is an inscrutable memory state (e.g., a call).
a61af66fc99e Initial load
duke
parents:
diff changeset
565 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 return NULL; // bail out
a61af66fc99e Initial load
duke
parents:
diff changeset
569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 //----------------------calculate_adr_type-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // Helper function. Notices when the given type of address hits top or bottom.
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // Also, asserts a cross-check of the type against the expected address type.
a61af66fc99e Initial load
duke
parents:
diff changeset
574 const TypePtr* MemNode::calculate_adr_type(const Type* t, const TypePtr* cross_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if (t == Type::TOP) return NULL; // does not touch memory any more?
a61af66fc99e Initial load
duke
parents:
diff changeset
576 #ifdef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
577 cross_check = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
578 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
579 if (!VerifyAliases || is_error_reported() || Node::in_dump()) cross_check = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
580 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
581 const TypePtr* tp = t->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if (tp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 assert(cross_check == NULL || cross_check == TypePtr::BOTTOM, "expected memory type must be wide");
a61af66fc99e Initial load
duke
parents:
diff changeset
584 return TypePtr::BOTTOM; // touches lots of memory
a61af66fc99e Initial load
duke
parents:
diff changeset
585 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // %%%% [phh] We don't check the alias index if cross_check is
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // TypeRawPtr::BOTTOM. Needs to be investigated.
a61af66fc99e Initial load
duke
parents:
diff changeset
589 if (cross_check != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
590 cross_check != TypePtr::BOTTOM &&
a61af66fc99e Initial load
duke
parents:
diff changeset
591 cross_check != TypeRawPtr::BOTTOM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // Recheck the alias index, to see if it has changed (due to a bug).
a61af66fc99e Initial load
duke
parents:
diff changeset
593 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
594 assert(C->get_alias_index(cross_check) == C->get_alias_index(tp),
a61af66fc99e Initial load
duke
parents:
diff changeset
595 "must stay in the original alias category");
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // The type of the address must be contained in the adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // disregarding "null"-ness.
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // (We make an exception for TypeRawPtr::BOTTOM, which is a bit bucket.)
a61af66fc99e Initial load
duke
parents:
diff changeset
599 const TypePtr* tp_notnull = tp->join(TypePtr::NOTNULL)->is_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
600 assert(cross_check->meet(tp_notnull) == cross_check,
a61af66fc99e Initial load
duke
parents:
diff changeset
601 "real address must not escape from expected memory type");
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
604 return tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 //------------------------adr_phi_is_loop_invariant----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // A helper function for Ideal_DU_postCCP to check if a Phi in a counted
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // loop is loop invariant. Make a quick traversal of Phi and associated
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // CastPP nodes, looking to see if they are a closed group within the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
612 bool MemNode::adr_phi_is_loop_invariant(Node* adr_phi, Node* cast) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // The idea is that the phi-nest must boil down to only CastPP nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // with the same data. This implies that any path into the loop already
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // includes such a CastPP, and so the original cast, whatever its input,
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // must be covered by an equivalent cast, with an earlier control input.
a61af66fc99e Initial load
duke
parents:
diff changeset
617 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
618
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // The loop entry input of the phi should be the unique dominating
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // node for every Phi/CastPP in the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
621 Unique_Node_List closure;
a61af66fc99e Initial load
duke
parents:
diff changeset
622 closure.push(adr_phi->in(LoopNode::EntryControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // Add the phi node and the cast to the worklist.
a61af66fc99e Initial load
duke
parents:
diff changeset
625 Unique_Node_List worklist;
a61af66fc99e Initial load
duke
parents:
diff changeset
626 worklist.push(adr_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if( cast != NULL ){
a61af66fc99e Initial load
duke
parents:
diff changeset
628 if( !cast->is_ConstraintCast() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 worklist.push(cast);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Begin recursive walk of phi nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
633 while( worklist.size() ){
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // Take a node off the worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
635 Node *n = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
636 if( !closure.member(n) ){
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // Add it to the closure.
a61af66fc99e Initial load
duke
parents:
diff changeset
638 closure.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // Make a sanity check to ensure we don't waste too much time here.
a61af66fc99e Initial load
duke
parents:
diff changeset
640 if( closure.size() > 20) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // This node is OK if:
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // - it is a cast of an identical value
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // - or it is a phi node (then we add its inputs to the worklist)
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // Otherwise, the node is not OK, and we presume the cast is not invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
645 if( n->is_ConstraintCast() ){
a61af66fc99e Initial load
duke
parents:
diff changeset
646 worklist.push(n->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
647 } else if( n->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 for( uint i = 1; i < n->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 worklist.push(n->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
651 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // Quit when the worklist is empty, and we've found no offending nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
658 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 //------------------------------Ideal_DU_postCCP-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // Find any cast-away of null-ness and keep its control. Null cast-aways are
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // going away in this pass and we need to make this memory op depend on the
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // gating null check.
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
665 Node *MemNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
666 return Ideal_common_DU_postCCP(ccp, this, in(MemNode::Address));
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
667 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // I tried to leave the CastPP's in. This makes the graph more accurate in
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // some sense; we get to keep around the knowledge that an oop is not-null
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // after some test. Alas, the CastPP's interfere with GVN (some values are
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // the regular oop, some are the CastPP of the oop, all merge at Phi's which
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // cannot collapse, etc). This cost us 10% on SpecJVM, even when I removed
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // some of the more trivial cases in the optimizer. Removing more useless
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // Phi's started allowing Loads to illegally float above null checks. I gave
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // up on this approach. CNC 10/20/2000
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
677 // This static method may be called not from MemNode (EncodePNode calls it).
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
678 // Only the control edge of the node 'n' might be updated.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
679 Node *MemNode::Ideal_common_DU_postCCP( PhaseCCP *ccp, Node* n, Node* adr ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
680 Node *skipped_cast = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // Need a null check? Regular static accesses do not because they are
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // from constant addresses. Array ops are gated by the range check (which
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // always includes a NULL check). Just check field ops.
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
684 if( n->in(MemNode::Control) == NULL ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // Scan upwards for the highest location we can place this memory op.
a61af66fc99e Initial load
duke
parents:
diff changeset
686 while( true ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 switch( adr->Opcode() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 case Op_AddP: // No change to NULL-ness, so peek thru AddP's
a61af66fc99e Initial load
duke
parents:
diff changeset
690 adr = adr->in(AddPNode::Base);
a61af66fc99e Initial load
duke
parents:
diff changeset
691 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
692
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
693 case Op_DecodeN: // No change to NULL-ness, so peek thru
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
694 adr = adr->in(1);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
695 continue;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
696
0
a61af66fc99e Initial load
duke
parents:
diff changeset
697 case Op_CastPP:
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // If the CastPP is useless, just peek on through it.
a61af66fc99e Initial load
duke
parents:
diff changeset
699 if( ccp->type(adr) == ccp->type(adr->in(1)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // Remember the cast that we've peeked though. If we peek
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // through more than one, then we end up remembering the highest
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // one, that is, if in a loop, the one closest to the top.
a61af66fc99e Initial load
duke
parents:
diff changeset
703 skipped_cast = adr;
a61af66fc99e Initial load
duke
parents:
diff changeset
704 adr = adr->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
705 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // CastPP is going away in this pass! We need this memory op to be
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // control-dependent on the test that is guarding the CastPP.
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
709 ccp->hash_delete(n);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
710 n->set_req(MemNode::Control, adr->in(0));
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
711 ccp->hash_insert(n);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
712 return n;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 case Op_Phi:
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // Attempt to float above a Phi to some dominating point.
a61af66fc99e Initial load
duke
parents:
diff changeset
716 if (adr->in(0) != NULL && adr->in(0)->is_CountedLoop()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // If we've already peeked through a Cast (which could have set the
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // control), we can't float above a Phi, because the skipped Cast
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // may not be loop invariant.
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if (adr_phi_is_loop_invariant(adr, skipped_cast)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 adr = adr->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
722 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 // Intentional fallthrough!
a61af66fc99e Initial load
duke
parents:
diff changeset
727
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // No obvious dominating point. The mem op is pinned below the Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // by the Phi itself. If the Phi goes away (no true value is merged)
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // then the mem op can float, but not indefinitely. It must be pinned
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // behind the controls leading to the Phi.
a61af66fc99e Initial load
duke
parents:
diff changeset
732 case Op_CheckCastPP:
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // These usually stick around to change address type, however a
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // useless one can be elided and we still need to pick up a control edge
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if (adr->in(0) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // This CheckCastPP node has NO control and is likely useless. But we
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // need check further up the ancestor chain for a control input to keep
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // the node in place. 4959717.
a61af66fc99e Initial load
duke
parents:
diff changeset
739 skipped_cast = adr;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 adr = adr->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
743 ccp->hash_delete(n);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
744 n->set_req(MemNode::Control, adr->in(0));
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
745 ccp->hash_insert(n);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
746 return n;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // List of "safe" opcodes; those that implicitly block the memory
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // op below any null check.
a61af66fc99e Initial load
duke
parents:
diff changeset
750 case Op_CastX2P: // no null checks on native pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
751 case Op_Parm: // 'this' pointer is not null
a61af66fc99e Initial load
duke
parents:
diff changeset
752 case Op_LoadP: // Loading from within a klass
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
753 case Op_LoadN: // Loading from within a klass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
754 case Op_LoadKlass: // Loading from within a klass
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
755 case Op_LoadNKlass: // Loading from within a klass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
756 case Op_ConP: // Loading from a klass
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
757 case Op_ConN: // Loading from a klass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
758 case Op_CreateEx: // Sucking up the guts of an exception oop
a61af66fc99e Initial load
duke
parents:
diff changeset
759 case Op_Con: // Reading from TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
760 case Op_CMoveP: // CMoveP is pinned
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
761 case Op_CMoveN: // CMoveN is pinned
0
a61af66fc99e Initial load
duke
parents:
diff changeset
762 break; // No progress
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 case Op_Proj: // Direct call to an allocation routine
a61af66fc99e Initial load
duke
parents:
diff changeset
765 case Op_SCMemProj: // Memory state from store conditional ops
a61af66fc99e Initial load
duke
parents:
diff changeset
766 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
767 {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 assert(adr->as_Proj()->_con == TypeFunc::Parms, "must be return value");
a61af66fc99e Initial load
duke
parents:
diff changeset
769 const Node* call = adr->in(0);
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
770 if (call->is_CallJava()) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
771 const CallJavaNode* call_java = call->as_CallJava();
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
772 const TypeTuple *r = call_java->tf()->range();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
773 assert(r->cnt() > TypeFunc::Parms, "must return value");
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
774 const Type* ret_type = r->field_at(TypeFunc::Parms);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
775 assert(ret_type && ret_type->isa_ptr(), "must return pointer");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // We further presume that this is one of
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // new_instance_Java, new_array_Java, or
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // the like, but do not assert for this.
a61af66fc99e Initial load
duke
parents:
diff changeset
779 } else if (call->is_Allocate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // similar case to new_instance_Java, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
781 } else if (!call->is_CallLeaf()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 // Projections from fetch_oop (OSR) are allowed as well.
a61af66fc99e Initial load
duke
parents:
diff changeset
783 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
787 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
789 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
791 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
794
a61af66fc99e Initial load
duke
parents:
diff changeset
795 return NULL; // No progress
a61af66fc99e Initial load
duke
parents:
diff changeset
796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798
a61af66fc99e Initial load
duke
parents:
diff changeset
799 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
800 uint LoadNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
801 uint LoadNode::cmp( const Node &n ) const
a61af66fc99e Initial load
duke
parents:
diff changeset
802 { return !Type::cmp( _type, ((LoadNode&)n)._type ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
803 const Type *LoadNode::bottom_type() const { return _type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
804 uint LoadNode::ideal_reg() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
805 return Matcher::base2reg[_type->base()];
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
809 void LoadNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
810 MemNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
811 if( !Verbose && !WizardMode ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // standard dump does this in Verbose and WizardMode
a61af66fc99e Initial load
duke
parents:
diff changeset
813 st->print(" #"); _type->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
816 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
817
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
818 #ifdef ASSERT
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
819 //----------------------------is_immutable_value-------------------------------
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
820 // Helper function to allow a raw load without control edge for some cases
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
821 bool LoadNode::is_immutable_value(Node* adr) {
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
822 return (adr->is_AddP() && adr->in(AddPNode::Base)->is_top() &&
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
823 adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
824 (adr->in(AddPNode::Offset)->find_intptr_t_con(-1) ==
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
825 in_bytes(JavaThread::osthread_offset())));
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
826 }
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
827 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 //----------------------------LoadNode::make-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // Polymorphic factory method:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
831 Node *LoadNode::make( PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypePtr* adr_type, const Type *rt, BasicType bt ) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
832 Compile* C = gvn.C;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
833
0
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // sanity check the alias category against the created node type
a61af66fc99e Initial load
duke
parents:
diff changeset
835 assert(!(adr_type->isa_oopptr() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
836 adr_type->offset() == oopDesc::klass_offset_in_bytes()),
a61af66fc99e Initial load
duke
parents:
diff changeset
837 "use LoadKlassNode instead");
a61af66fc99e Initial load
duke
parents:
diff changeset
838 assert(!(adr_type->isa_aryptr() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
839 adr_type->offset() == arrayOopDesc::length_offset_in_bytes()),
a61af66fc99e Initial load
duke
parents:
diff changeset
840 "use LoadRangeNode instead");
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
841 // Check control edge of raw loads
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
842 assert( ctl != NULL || C->get_alias_index(adr_type) != Compile::AliasIdxRaw ||
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
843 // oop will be recorded in oop map if load crosses safepoint
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
844 rt->isa_oopptr() || is_immutable_value(adr),
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
845 "raw memory operations should have control edge");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
846 switch (bt) {
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
847 case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() );
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
848 case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() );
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
849 case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() );
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
850 case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() );
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
851 case T_SHORT: return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int() );
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
852 case T_LONG: return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long() );
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
853 case T_FLOAT: return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt );
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
854 case T_DOUBLE: return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt );
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
855 case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr() );
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
856 case T_OBJECT:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
857 #ifdef _LP64
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
858 if (adr->bottom_type()->is_ptr_to_narrowoop()) {
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
859 Node* load = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop()));
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
860 return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr());
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
861 } else
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
862 #endif
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
863 {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
864 assert(!adr->bottom_type()->is_ptr_to_narrowoop(), "should have got back a narrow oop");
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
865 return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr());
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
866 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
867 }
a61af66fc99e Initial load
duke
parents:
diff changeset
868 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
869 return (LoadNode*)NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872 LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 bool require_atomic = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
874 return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), require_atomic);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879
a61af66fc99e Initial load
duke
parents:
diff changeset
880 //------------------------------hash-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
881 uint LoadNode::hash() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // unroll addition of interesting fields
a61af66fc99e Initial load
duke
parents:
diff changeset
883 return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 //---------------------------can_see_stored_value------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
887 // This routine exists to make sure this set of tests is done the same
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // everywhere. We need to make a coordinated change: first LoadNode::Ideal
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // will change the graph shape in a way which makes memory alive twice at the
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // same time (uses the Oracle model of aliasing), then some
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // LoadXNode::Identity will fold things back to the equivalence-class model
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // of aliasing.
a61af66fc99e Initial load
duke
parents:
diff changeset
893 Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 Node* ld_adr = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
895
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
896 const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
897 Compile::AliasType* atp = tp != NULL ? phase->C->alias_type(tp) : NULL;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
898 if (EliminateAutoBox && atp != NULL && atp->index() >= Compile::AliasIdxRaw &&
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
899 atp->field() != NULL && !atp->field()->is_volatile()) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
900 uint alias_idx = atp->index();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
901 bool final = atp->field()->is_final();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
902 Node* result = NULL;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
903 Node* current = st;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
904 // Skip through chains of MemBarNodes checking the MergeMems for
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
905 // new states for the slice of this load. Stop once any other
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
906 // kind of node is encountered. Loads from final memory can skip
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
907 // through any kind of MemBar but normal loads shouldn't skip
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
908 // through MemBarAcquire since the could allow them to move out of
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
909 // a synchronized region.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
910 while (current->is_Proj()) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
911 int opc = current->in(0)->Opcode();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
912 if ((final && opc == Op_MemBarAcquire) ||
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
913 opc == Op_MemBarRelease || opc == Op_MemBarCPUOrder) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
914 Node* mem = current->in(0)->in(TypeFunc::Memory);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
915 if (mem->is_MergeMem()) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
916 MergeMemNode* merge = mem->as_MergeMem();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
917 Node* new_st = merge->memory_at(alias_idx);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
918 if (new_st == merge->base_memory()) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
919 // Keep searching
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
920 current = merge->base_memory();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
921 continue;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
922 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
923 // Save the new memory state for the slice and fall through
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
924 // to exit.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
925 result = new_st;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
926 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
927 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
928 break;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
929 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
930 if (result != NULL) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
931 st = result;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
932 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
933 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
934
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
935
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // Loop around twice in the case Load -> Initialize -> Store.
a61af66fc99e Initial load
duke
parents:
diff changeset
937 // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.)
a61af66fc99e Initial load
duke
parents:
diff changeset
938 for (int trip = 0; trip <= 1; trip++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 if (st->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 Node* st_adr = st->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
942 if (!phase->eqv(st_adr, ld_adr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // Try harder before giving up... Match raw and non-raw pointers.
a61af66fc99e Initial load
duke
parents:
diff changeset
944 intptr_t st_off = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
945 AllocateNode* alloc = AllocateNode::Ideal_allocation(st_adr, phase, st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
946 if (alloc == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
947 intptr_t ld_off = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
948 AllocateNode* allo2 = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
949 if (alloc != allo2) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
950 if (ld_off != st_off) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // At this point we have proven something like this setup:
a61af66fc99e Initial load
duke
parents:
diff changeset
952 // A = Allocate(...)
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // L = LoadQ(, AddP(CastPP(, A.Parm),, #Off))
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // S = StoreQ(, AddP(, A.Parm , #Off), V)
a61af66fc99e Initial load
duke
parents:
diff changeset
955 // (Actually, we haven't yet proven the Q's are the same.)
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // In other words, we are loading from a casted version of
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // the same pointer-and-offset that we stored to.
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // Thus, we are able to replace L by V.
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // Now prove that we have a LoadQ matched to a StoreQ, for some Q.
a61af66fc99e Initial load
duke
parents:
diff changeset
961 if (store_Opcode() != st->Opcode())
a61af66fc99e Initial load
duke
parents:
diff changeset
962 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
963 return st->in(MemNode::ValueIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965
a61af66fc99e Initial load
duke
parents:
diff changeset
966 intptr_t offset = 0; // scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // A load from a freshly-created object always returns zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // (This can happen after LoadNode::Ideal resets the load's memory input
a61af66fc99e Initial load
duke
parents:
diff changeset
970 // to find_captured_store, which returned InitializeNode::zero_memory.)
a61af66fc99e Initial load
duke
parents:
diff changeset
971 if (st->is_Proj() && st->in(0)->is_Allocate() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
972 st->in(0) == AllocateNode::Ideal_allocation(ld_adr, phase, offset) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
973 offset >= st->in(0)->as_Allocate()->minimum_header_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // return a zero value for the load's basic type
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // (This is one of the few places where a generic PhaseTransform
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // can create new nodes. Think of it as lazily manifesting
a61af66fc99e Initial load
duke
parents:
diff changeset
977 // virtually pre-existing constants.)
a61af66fc99e Initial load
duke
parents:
diff changeset
978 return phase->zerocon(memory_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // A load from an initialization barrier can match a captured store.
a61af66fc99e Initial load
duke
parents:
diff changeset
982 if (st->is_Proj() && st->in(0)->is_Initialize()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 InitializeNode* init = st->in(0)->as_Initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
984 AllocateNode* alloc = init->allocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
985 if (alloc != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
986 alloc == AllocateNode::Ideal_allocation(ld_adr, phase, offset)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // examine a captured store value
a61af66fc99e Initial load
duke
parents:
diff changeset
988 st = init->find_captured_store(offset, memory_size(), phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
989 if (st != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
990 continue; // take one more trip around
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 }
a61af66fc99e Initial load
duke
parents:
diff changeset
999
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1000 //----------------------is_instance_field_load_with_local_phi------------------
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1001 bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1002 if( in(MemNode::Memory)->is_Phi() && in(MemNode::Memory)->in(0) == ctrl &&
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1003 in(MemNode::Address)->is_AddP() ) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1004 const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1005 // Only instances.
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
1006 if( t_oop != NULL && t_oop->is_known_instance_field() &&
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1007 t_oop->offset() != Type::OffsetBot &&
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1008 t_oop->offset() != Type::OffsetTop) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1009 return true;
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1010 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1011 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1012 return false;
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1013 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1014
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // Loads are identity if previous store is to same address
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 Node *LoadNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // If the previous store-maker is the right kind of Store, and the store is
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // to the same address, then we are equal to the value stored.
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 Node* mem = in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 Node* value = can_see_stored_value(mem, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 if( value ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // byte, short & char stores truncate naturally.
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // A load has to load the truncated value which requires
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // some sort of masking operation and that requires an
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // Ideal call instead of an Identity call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 if (memory_size() < BytesPerInt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // If the input to the store does not fit with the load's result type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // it must be truncated via an Ideal call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 if (!phase->type(value)->higher_equal(phase->type(this)))
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // (This works even when value is a Con, but LoadNode::Value
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // usually runs first, producing the singleton type of the Con.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 return value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 }
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1037
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1038 // Search for an existing data phi which was generated before for the same
605
98cb887364d3 6810672: Comment typos
twisti
parents: 583
diff changeset
1039 // instance's field to avoid infinite generation of phis in a loop.
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1040 Node *region = mem->in(0);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1041 if (is_instance_field_load_with_local_phi(region)) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1042 const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1043 int this_index = phase->C->get_alias_index(addr_t);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1044 int this_offset = addr_t->offset();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1045 int this_id = addr_t->is_oopptr()->instance_id();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1046 const Type* this_type = bottom_type();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1047 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1048 Node* phi = region->fast_out(i);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1049 if (phi->is_Phi() && phi != mem &&
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1050 phi->as_Phi()->is_same_inst_field(this_type, this_id, this_index, this_offset)) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1051 return phi;
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1052 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1053 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1054 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1055
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1058
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1059
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1060 // Returns true if the AliasType refers to the field that holds the
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1061 // cached box array. Currently only handles the IntegerCache case.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1062 static bool is_autobox_cache(Compile::AliasType* atp) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1063 if (atp != NULL && atp->field() != NULL) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1064 ciField* field = atp->field();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1065 ciSymbol* klass = field->holder()->name();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1066 if (field->name() == ciSymbol::cache_field_name() &&
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1067 field->holder()->uses_default_loader() &&
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1068 klass == ciSymbol::java_lang_Integer_IntegerCache()) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1069 return true;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1070 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1071 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1072 return false;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1073 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1074
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1075 // Fetch the base value in the autobox array
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1076 static bool fetch_autobox_base(Compile::AliasType* atp, int& cache_offset) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1077 if (atp != NULL && atp->field() != NULL) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1078 ciField* field = atp->field();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1079 ciSymbol* klass = field->holder()->name();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1080 if (field->name() == ciSymbol::cache_field_name() &&
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1081 field->holder()->uses_default_loader() &&
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1082 klass == ciSymbol::java_lang_Integer_IntegerCache()) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1083 assert(field->is_constant(), "what?");
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1084 ciObjArray* array = field->constant_value().as_object()->as_obj_array();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1085 // Fetch the box object at the base of the array and get its value
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1086 ciInstance* box = array->obj_at(0)->as_instance();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1087 ciInstanceKlass* ik = box->klass()->as_instance_klass();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1088 if (ik->nof_nonstatic_fields() == 1) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1089 // This should be true nonstatic_field_at requires calling
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1090 // nof_nonstatic_fields so check it anyway
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1091 ciConstant c = box->field_value(ik->nonstatic_field_at(0));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1092 cache_offset = c.as_int();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1093 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1094 return true;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1095 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1096 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1097 return false;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1098 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1099
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1100 // Returns true if the AliasType refers to the value field of an
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1101 // autobox object. Currently only handles Integer.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1102 static bool is_autobox_object(Compile::AliasType* atp) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1103 if (atp != NULL && atp->field() != NULL) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1104 ciField* field = atp->field();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1105 ciSymbol* klass = field->holder()->name();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1106 if (field->name() == ciSymbol::value_name() &&
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1107 field->holder()->uses_default_loader() &&
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1108 klass == ciSymbol::java_lang_Integer()) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1109 return true;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1110 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1111 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1112 return false;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1113 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1114
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1115
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1116 // We're loading from an object which has autobox behaviour.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1117 // If this object is result of a valueOf call we'll have a phi
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1118 // merging a newly allocated object and a load from the cache.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1119 // We want to replace this load with the original incoming
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1120 // argument to the valueOf call.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1121 Node* LoadNode::eliminate_autobox(PhaseGVN* phase) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1122 Node* base = in(Address)->in(AddPNode::Base);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1123 if (base->is_Phi() && base->req() == 3) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1124 AllocateNode* allocation = NULL;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1125 int allocation_index = -1;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1126 int load_index = -1;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1127 for (uint i = 1; i < base->req(); i++) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1128 allocation = AllocateNode::Ideal_allocation(base->in(i), phase);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1129 if (allocation != NULL) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1130 allocation_index = i;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1131 load_index = 3 - allocation_index;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1132 break;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1133 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1134 }
583
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1135 bool has_load = ( allocation != NULL &&
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1136 (base->in(load_index)->is_Load() ||
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1137 base->in(load_index)->is_DecodeN() &&
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1138 base->in(load_index)->in(1)->is_Load()) );
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1139 if (has_load && in(Memory)->is_Phi() && in(Memory)->in(0) == base->in(0)) {
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1140 // Push the loads from the phi that comes from valueOf up
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1141 // through it to allow elimination of the loads and the recovery
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1142 // of the original value.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1143 Node* mem_phi = in(Memory);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1144 Node* offset = in(Address)->in(AddPNode::Offset);
553
041fe019d769 6791132: bad control in autobox split code
never
parents: 420
diff changeset
1145 Node* region = base->in(0);
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1146
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1147 Node* in1 = clone();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1148 Node* in1_addr = in1->in(Address)->clone();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1149 in1_addr->set_req(AddPNode::Base, base->in(allocation_index));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1150 in1_addr->set_req(AddPNode::Address, base->in(allocation_index));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1151 in1_addr->set_req(AddPNode::Offset, offset);
553
041fe019d769 6791132: bad control in autobox split code
never
parents: 420
diff changeset
1152 in1->set_req(0, region->in(allocation_index));
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1153 in1->set_req(Address, in1_addr);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1154 in1->set_req(Memory, mem_phi->in(allocation_index));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1155
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1156 Node* in2 = clone();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1157 Node* in2_addr = in2->in(Address)->clone();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1158 in2_addr->set_req(AddPNode::Base, base->in(load_index));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1159 in2_addr->set_req(AddPNode::Address, base->in(load_index));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1160 in2_addr->set_req(AddPNode::Offset, offset);
553
041fe019d769 6791132: bad control in autobox split code
never
parents: 420
diff changeset
1161 in2->set_req(0, region->in(load_index));
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1162 in2->set_req(Address, in2_addr);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1163 in2->set_req(Memory, mem_phi->in(load_index));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1164
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1165 in1_addr = phase->transform(in1_addr);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1166 in1 = phase->transform(in1);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1167 in2_addr = phase->transform(in2_addr);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1168 in2 = phase->transform(in2);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1169
553
041fe019d769 6791132: bad control in autobox split code
never
parents: 420
diff changeset
1170 PhiNode* result = PhiNode::make_blank(region, this);
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1171 result->set_req(allocation_index, in1);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1172 result->set_req(load_index, in2);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1173 return result;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1174 }
583
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1175 } else if (base->is_Load() ||
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1176 base->is_DecodeN() && base->in(1)->is_Load()) {
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1177 if (base->is_DecodeN()) {
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1178 // Get LoadN node which loads cached Integer object
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1179 base = base->in(1);
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1180 }
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1181 // Eliminate the load of Integer.value for integers from the cache
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1182 // array by deriving the value from the index into the array.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1183 // Capture the offset of the load and then reverse the computation.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1184 Node* load_base = base->in(Address)->in(AddPNode::Base);
583
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1185 if (load_base->is_DecodeN()) {
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1186 // Get LoadN node which loads IntegerCache.cache field
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1187 load_base = load_base->in(1);
5d75ab5f6698 6807084: AutoBox elimination is broken with compressed oops
kvn
parents: 570
diff changeset
1188 }
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1189 if (load_base != NULL) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1190 Compile::AliasType* atp = phase->C->alias_type(load_base->adr_type());
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1191 intptr_t cache_offset;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1192 int shift = -1;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1193 Node* cache = NULL;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1194 if (is_autobox_cache(atp)) {
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 17
diff changeset
1195 shift = exact_log2(type2aelembytes(T_OBJECT));
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1196 cache = AddPNode::Ideal_base_and_offset(load_base->in(Address), phase, cache_offset);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1197 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1198 if (cache != NULL && base->in(Address)->is_AddP()) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1199 Node* elements[4];
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1200 int count = base->in(Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1201 int cache_low;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1202 if (count > 0 && fetch_autobox_base(atp, cache_low)) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1203 int offset = arrayOopDesc::base_offset_in_bytes(memory_type()) - (cache_low << shift);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1204 // Add up all the offsets making of the address of the load
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1205 Node* result = elements[0];
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1206 for (int i = 1; i < count; i++) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1207 result = phase->transform(new (phase->C, 3) AddXNode(result, elements[i]));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1208 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1209 // Remove the constant offset from the address and then
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1210 // remove the scaling of the offset to recover the original index.
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1211 result = phase->transform(new (phase->C, 3) AddXNode(result, phase->MakeConX(-offset)));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1212 if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1213 // Peel the shift off directly but wrap it in a dummy node
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1214 // since Ideal can't return existing nodes
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1215 result = new (phase->C, 3) RShiftXNode(result->in(1), phase->intcon(0));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1216 } else {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1217 result = new (phase->C, 3) RShiftXNode(result, phase->intcon(shift));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1218 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1219 #ifdef _LP64
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1220 result = new (phase->C, 2) ConvL2INode(phase->transform(result));
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1221 #endif
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1222 return result;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1223 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1224 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1225 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1226 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1227 return NULL;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1228 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1229
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1230 //------------------------------split_through_phi------------------------------
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1231 // Split instance field load through Phi.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1232 Node *LoadNode::split_through_phi(PhaseGVN *phase) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1233 Node* mem = in(MemNode::Memory);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1234 Node* address = in(MemNode::Address);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1235 const TypePtr *addr_t = phase->type(address)->isa_ptr();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1236 const TypeOopPtr *t_oop = addr_t->isa_oopptr();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1237
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1238 assert(mem->is_Phi() && (t_oop != NULL) &&
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
1239 t_oop->is_known_instance_field(), "invalide conditions");
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1240
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1241 Node *region = mem->in(0);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1242 if (region == NULL) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1243 return NULL; // Wait stable graph
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1244 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1245 uint cnt = mem->req();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1246 for( uint i = 1; i < cnt; i++ ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1247 Node *in = mem->in(i);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1248 if( in == NULL ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1249 return NULL; // Wait stable graph
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1250 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1251 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1252 // Check for loop invariant.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1253 if (cnt == 3) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1254 for( uint i = 1; i < cnt; i++ ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1255 Node *in = mem->in(i);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1256 Node* m = MemNode::optimize_memory_chain(in, addr_t, phase);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1257 if (m == mem) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1258 set_req(MemNode::Memory, mem->in(cnt - i)); // Skip this phi.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1259 return this;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1260 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1261 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1262 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1263 // Split through Phi (see original code in loopopts.cpp).
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1264 assert(phase->C->have_alias_type(addr_t), "instance should have alias type");
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1265
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1266 // Do nothing here if Identity will find a value
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1267 // (to avoid infinite chain of value phis generation).
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1268 if ( !phase->eqv(this, this->Identity(phase)) )
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1269 return NULL;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1270
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1271 // Skip the split if the region dominates some control edge of the address.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1272 if (cnt == 3 && !MemNode::all_controls_dominate(address, region))
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1273 return NULL;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1274
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1275 const Type* this_type = this->bottom_type();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1276 int this_index = phase->C->get_alias_index(addr_t);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1277 int this_offset = addr_t->offset();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1278 int this_iid = addr_t->is_oopptr()->instance_id();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1279 int wins = 0;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1280 PhaseIterGVN *igvn = phase->is_IterGVN();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1281 Node *phi = new (igvn->C, region->req()) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1282 for( uint i = 1; i < region->req(); i++ ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1283 Node *x;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1284 Node* the_clone = NULL;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1285 if( region->in(i) == phase->C->top() ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1286 x = phase->C->top(); // Dead path? Use a dead data op
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1287 } else {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1288 x = this->clone(); // Else clone up the data op
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1289 the_clone = x; // Remember for possible deletion.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1290 // Alter data node to use pre-phi inputs
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1291 if( this->in(0) == region ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1292 x->set_req( 0, region->in(i) );
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1293 } else {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1294 x->set_req( 0, NULL );
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1295 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1296 for( uint j = 1; j < this->req(); j++ ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1297 Node *in = this->in(j);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1298 if( in->is_Phi() && in->in(0) == region )
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1299 x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1300 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1301 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1302 // Check for a 'win' on some paths
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1303 const Type *t = x->Value(igvn);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1304
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1305 bool singleton = t->singleton();
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1306
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1307 // See comments in PhaseIdealLoop::split_thru_phi().
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1308 if( singleton && t == Type::TOP ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1309 singleton &= region->is_Loop() && (i != LoopNode::EntryControl);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1310 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1311
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1312 if( singleton ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1313 wins++;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1314 x = igvn->makecon(t);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1315 } else {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1316 // We now call Identity to try to simplify the cloned node.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1317 // Note that some Identity methods call phase->type(this).
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1318 // Make sure that the type array is big enough for
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1319 // our new node, even though we may throw the node away.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1320 // (This tweaking with igvn only works because x is a new node.)
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1321 igvn->set_type(x, t);
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
1322 // If x is a TypeNode, capture any more-precise type permanently into Node
605
98cb887364d3 6810672: Comment typos
twisti
parents: 583
diff changeset
1323 // otherwise it will be not updated during igvn->transform since
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
1324 // igvn->type(x) is set to x->Value() already.
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
1325 x->raise_bottom_type(t);
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1326 Node *y = x->Identity(igvn);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1327 if( y != x ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1328 wins++;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1329 x = y;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1330 } else {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1331 y = igvn->hash_find(x);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1332 if( y ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1333 wins++;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1334 x = y;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1335 } else {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1336 // Else x is a new node we are keeping
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1337 // We do not need register_new_node_with_optimizer
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1338 // because set_type has already been called.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1339 igvn->_worklist.push(x);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1340 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1341 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1342 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1343 if (x != the_clone && the_clone != NULL)
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1344 igvn->remove_dead_node(the_clone);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1345 phi->set_req(i, x);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1346 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1347 if( wins > 0 ) {
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1348 // Record Phi
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1349 igvn->register_new_node_with_optimizer(phi);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1350 return phi;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1351 }
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1352 igvn->remove_dead_node(phi);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1353 return NULL;
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1354 }
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1355
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // If the load is from Field memory and the pointer is non-null, we can
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // zero out the control input.
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 // If the offset is constant and the base is an object allocation,
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // try to hook me up to the exact initializing store.
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 Node* p = MemNode::Ideal_common(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 if (p) return (p == NodeSentinel) ? NULL : p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1364
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 Node* ctrl = in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 Node* address = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 // Skip up past a SafePoint control. Cannot do this for Stores because
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // pointer stores & cardmarks must stay on the same side of a SafePoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 if( ctrl != NULL && ctrl->Opcode() == Op_SafePoint &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 ctrl = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 set_req(MemNode::Control,ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1375
708
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1376 intptr_t ignore = 0;
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1377 Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore);
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1378 if (base != NULL
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1379 && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw) {
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1380 // Check for useless control edge in some common special cases
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1381 if (in(MemNode::Control) != NULL
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 && phase->type(base)->higher_equal(TypePtr::NOTNULL)
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
1383 && all_controls_dominate(base, phase->C->start())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // A method-invariant, non-null address (constant or 'this' argument).
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 set_req(MemNode::Control, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 }
708
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1387
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1388 if (EliminateAutoBox && can_reshape) {
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1389 assert(!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "the autobox pointer should be non-null");
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1390 Compile::AliasType* atp = phase->C->alias_type(adr_type());
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1391 if (is_autobox_object(atp)) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1392 Node* result = eliminate_autobox(phase);
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1393 if (result != NULL) return result;
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1394 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1395 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1396 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1397
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1398 Node* mem = in(MemNode::Memory);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1399 const TypePtr *addr_t = phase->type(address)->isa_ptr();
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1400
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1401 if (addr_t != NULL) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1402 // try to optimize our memory input
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1403 Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, phase);
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1404 if (opt_mem != mem) {
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1405 set_req(MemNode::Memory, opt_mem);
305
ab075d07f1ba 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 293
diff changeset
1406 if (phase->type( opt_mem ) == Type::TOP) return NULL;
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1407 return this;
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1408 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1409 const TypeOopPtr *t_oop = addr_t->isa_oopptr();
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1410 if (can_reshape && opt_mem->is_Phi() &&
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
1411 (t_oop != NULL) && t_oop->is_known_instance_field()) {
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1412 // Split instance field load through Phi.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1413 Node* result = split_through_phi(phase);
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
1414 if (result != NULL) return result;
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1415 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1416 }
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 68
diff changeset
1417
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // Check for prior store with a different base or offset; make Load
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // independent. Skip through any number of them. Bail out if the stores
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 // are in an endless dead cycle and report no progress. This is a key
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // transform for Reflection. However, if after skipping through the Stores
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 // we can't then fold up against a prior store do NOT do the transform as
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // this amounts to using the 'Oracle' model of aliasing. It leaves the same
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // array memory alive twice: once for the hoisted Load and again after the
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 // bypassed Store. This situation only works if EVERYBODY who does
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 // anti-dependence work knows how to bypass. I.e. we need all
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 // anti-dependence checks to ask the same Oracle. Right now, that Oracle is
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 // the alias index stuff. So instead, peek through Stores and IFF we can
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // fold up, do so.
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 Node* prev_mem = find_previous_store(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // Steps (a), (b): Walk past independent stores to find an exact match.
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 // (c) See if we can fold up on the spot, but don't fold up here.
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
1434 // Fold-up might require truncation (for LoadB/LoadS/LoadUS) or
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // just return a prior value, which is done by Identity calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 if (can_see_stored_value(prev_mem, phase)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // Make ready for step (d):
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 set_req(MemNode::Memory, prev_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1442
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 return NULL; // No further progress
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // Helper to recognize certain Klass fields which are invariant across
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // some group of array types (e.g., int[] or all T[] where T < Object).
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 const Type*
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 LoadNode::load_array_final_field(const TypeKlassPtr *tkls,
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 ciKlass* klass) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 if (tkls->offset() == Klass::modifier_flags_offset_in_bytes() + (int)sizeof(oopDesc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 // The field is Klass::_modifier_flags. Return its (constant) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 // (Folds up the 2nd indirection in aClassConstant.getModifiers().)
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags");
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 return TypeInt::make(klass->modifier_flags());
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 if (tkls->offset() == Klass::access_flags_offset_in_bytes() + (int)sizeof(oopDesc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 // The field is Klass::_access_flags. Return its (constant) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).)
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags");
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 return TypeInt::make(klass->access_flags());
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 if (tkls->offset() == Klass::layout_helper_offset_in_bytes() + (int)sizeof(oopDesc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // The field is Klass::_layout_helper. Return its constant value if known.
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper");
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 return TypeInt::make(klass->layout_helper());
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // No match.
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 //------------------------------Value-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 const Type *LoadNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 Node* mem = in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 const Type *t1 = phase->type(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 if (t1 == Type::TOP) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 Node* adr = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 const TypePtr* tp = phase->type(adr)->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 if (tp == NULL || tp->empty()) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 int off = tp->offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 assert(off != Type::OffsetTop, "case covered by TypePtr::empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1484
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 // Try to guess loaded type from pointer type
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 if (tp->base() == Type::AryPtr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 const Type *t = tp->is_aryptr()->elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // Don't do this for integer types. There is only potential profit if
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 // the element type t is lower than _type; that is, for int types, if _type is
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 // more restrictive than t. This only happens here if one is short and the other
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 // char (both 16 bits), and in those cases we've made an intentional decision
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 // to use one kind of load over the other. See AndINode::Ideal and 4965907.
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 // Also, do not try to narrow the type for a LoadKlass, regardless of offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 // Yes, it is possible to encounter an expression like (LoadKlass p1:(AddP x x 8))
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // where the _gvn.type of the AddP is wider than 8. This occurs when an earlier
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 // copy p0 of (AddP x x 8) has been proven equal to p1, and the p0 has been
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // subsumed by p1. If p1 is on the worklist but has not yet been re-transformed,
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 // it is possible that p1 will have a type like Foo*[int+]:NotNull*+any.
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 // In fact, that could have been the original type of p1, and p1 could have
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 // had an original form like p1:(AddP x x (LShiftL quux 3)), where the
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 // expression (LShiftL quux 3) independently optimized to the constant 8.
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 if ((t->isa_int() == NULL) && (t->isa_long() == NULL)
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
1504 && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // t might actually be lower than _type, if _type is a unique
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // concrete subclass of abstract class t.
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 // Make sure the reference is not into the header, by comparing
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 // the offset against the offset of the start of the array's data.
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 // Different array types begin at slightly different offsets (12 vs. 16).
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 // We choose T_BYTE as an example base type that is least restrictive
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // as to alignment, which will therefore produce the smallest
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 // possible base offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 if ((uint)off >= (uint)min_base_off) { // is the offset beyond the header?
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 const Type* jt = t->join(_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // In any case, do not allow the join, per se, to empty out the type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 if (jt->empty() && !t->empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 // This can happen if a interface-typed array narrows to a class type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 jt = _type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 }
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1521
708
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1522 if (EliminateAutoBox && adr->is_AddP()) {
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1523 // The pointers in the autobox arrays are always non-null
708
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1524 Node* base = adr->in(AddPNode::Base);
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1525 if (base != NULL &&
f2049ae95c3d 6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents: 681
diff changeset
1526 !phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
17
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1527 Compile::AliasType* atp = phase->C->alias_type(base->adr_type());
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1528 if (is_autobox_cache(atp)) {
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1529 return jt->join(TypePtr::NOTNULL)->is_ptr();
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1530 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1531 }
ff5961f4c095 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents: 0
diff changeset
1532 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 return jt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 } else if (tp->base() == Type::InstPtr) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1537 const TypeInstPtr* tinst = tp->is_instptr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1538 ciKlass* klass = tinst->klass();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 assert( off != Type::OffsetBot ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 // arrays can be cast to Objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 tp->is_oopptr()->klass()->is_java_lang_Object() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // unsafe field access may not have a constant offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 phase->C->has_unsafe_access(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 "Field accesses must be precise" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 // For oop loads, we expect the _type to be precise
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1546 if (OptimizeStringConcat && klass == phase->C->env()->String_klass() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1547 adr->is_AddP() && off != Type::OffsetBot) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1548 // For constant Strings treat the fields as compile time constants.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1549 Node* base = adr->in(AddPNode::Base);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1550 if (base->Opcode() == Op_ConP) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1551 const TypeOopPtr* t = phase->type(base)->isa_oopptr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1552 ciObject* string = t->const_oop();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1553 ciConstant constant = string->as_instance()->field_value_by_offset(off);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1554 if (constant.basic_type() == T_INT) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1555 return TypeInt::make(constant.as_int());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1556 } else if (constant.basic_type() == T_ARRAY) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1557 if (adr->bottom_type()->is_ptr_to_narrowoop()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1558 return TypeNarrowOop::make_from_constant(constant.as_object());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1559 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1560 return TypeOopPtr::make_from_constant(constant.as_object());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1561 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1562 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1563 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1062
diff changeset
1564 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 } else if (tp->base() == Type::KlassPtr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 assert( off != Type::OffsetBot ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 // arrays can be cast to Objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 tp->is_klassptr()->klass()->is_java_lang_Object() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 // also allow array-loading from the primary supertype
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 // array during subtype checks
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 Opcode() == Op_LoadKlass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 "Field accesses must be precise" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 // For klass/static loads, we expect the _type to be precise
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1575
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 const TypeKlassPtr *tkls = tp->isa_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 if (tkls != NULL && !StressReflectiveCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 ciKlass* klass = tkls->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 if (klass->is_loaded() && tkls->klass_is_exact()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 // We are loading a field from a Klass metaobject whose identity
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // is known at compile time (the type is "exact" or "precise").
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // Check for fields we know are maintained as constants by the VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 if (tkls->offset() == Klass::super_check_offset_offset_in_bytes() + (int)sizeof(oopDesc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // The field is Klass::_super_check_offset. Return its (constant) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 // (Folds up type checking code.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 assert(Opcode() == Op_LoadI, "must load an int from _super_check_offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 return TypeInt::make(klass->super_check_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 // Compute index into primary_supers array
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 juint depth = (tkls->offset() - (Klass::primary_supers_offset_in_bytes() + (int)sizeof(oopDesc))) / sizeof(klassOop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 // Check for overflowing; use unsigned compare to handle the negative case.
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 if( depth < ciKlass::primary_super_limit() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 // The field is an element of Klass::_primary_supers. Return its (constant) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 // (Folds up type checking code.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 ciKlass *ss = klass->super_of_depth(depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 return ss ? TypeKlassPtr::make(ss) : TypePtr::NULL_PTR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 const Type* aift = load_array_final_field(tkls, klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 if (aift != NULL) return aift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 if (tkls->offset() == in_bytes(arrayKlass::component_mirror_offset()) + (int)sizeof(oopDesc)
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 && klass->is_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 // The field is arrayKlass::_component_mirror. Return its (constant) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // (Folds up aClassConstant.getComponentType, common in Arrays.copyOf.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 assert(Opcode() == Op_LoadP, "must load an oop from _component_mirror");
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 return TypeInstPtr::make(klass->as_array_klass()->component_mirror());
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 if (tkls->offset() == Klass::java_mirror_offset_in_bytes() + (int)sizeof(oopDesc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 // The field is Klass::_java_mirror. Return its (constant) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 // (Folds up the 2nd indirection in anObjConstant.getClass().)
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 assert(Opcode() == Op_LoadP, "must load an oop from _java_mirror");
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 return TypeInstPtr::make(klass->java_mirror());
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1615
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // We can still check if we are loading from the primary_supers array at a
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 // shallow enough depth. Even though the klass is not exact, entries less
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // than or equal to its super depth are correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 if (klass->is_loaded() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 ciType *inner = klass->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 while( inner->is_obj_array_klass() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 inner = inner->as_obj_array_klass()->base_element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 if( inner->is_instance_klass() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 !inner->as_instance_klass()->flags().is_interface() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 // Compute index into primary_supers array
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 juint depth = (tkls->offset() - (Klass::primary_supers_offset_in_bytes() + (int)sizeof(oopDesc))) / sizeof(klassOop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 // Check for overflowing; use unsigned compare to handle the negative case.
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 if( depth < ciKlass::primary_super_limit() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 depth <= klass->super_depth() ) { // allow self-depth checks to handle self-check case
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 // The field is an element of Klass::_primary_supers. Return its (constant) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 // (Folds up type checking code.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 ciKlass *ss = klass->super_of_depth(depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 return ss ? TypeKlassPtr::make(ss) : TypePtr::NULL_PTR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1638
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // If the type is enough to determine that the thing is not an array,
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 // we can give the layout_helper a positive interval type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // This will help short-circuit some reflective code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 if (tkls->offset() == Klass::layout_helper_offset_in_bytes() + (int)sizeof(oopDesc)
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 && !klass->is_array_klass() // not directly typed as an array
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 && !klass->is_interface() // specifically not Serializable & Cloneable
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 && !klass->is_java_lang_Object() // not the supertype of all T[]
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // Note: When interfaces are reliable, we can narrow the interface
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // test to (klass != Serializable && klass != Cloneable).
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 assert(Opcode() == Op_LoadI, "must load an int from _layout_helper");
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 jint min_size = Klass::instance_layout_helper(oopDesc::header_size(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 // The key property of this type is that it folds up tests
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // for array-ness, since it proves that the layout_helper is positive.
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // Thus, a generic value like the basic object layout helper works fine.
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 return TypeInt::make(min_size, max_jint, Type::WidenMin);
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1657
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 // If we are loading from a freshly-allocated object, produce a zero,
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 // if the load is provably beyond the header of the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 // (Also allow a variable load from a fresh array to produce zero.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 if (ReduceFieldZeroing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 Node* value = can_see_stored_value(mem,phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 if (value != NULL && value->is_Con())
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 return value->bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1666
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1667 const TypeOopPtr *tinst = tp->isa_oopptr();
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
1668 if (tinst != NULL && tinst->is_known_instance_field()) {
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1669 // If we have an instance type and our memory input is the
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1670 // programs's initial memory state, there is no matching store,
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1671 // so just return a zero of the appropriate type
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1672 Node *mem = in(MemNode::Memory);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1673 if (mem->is_Parm() && mem->in(0)->is_Start()) {
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1674 assert(mem->as_Parm()->_con == TypeFunc::Memory, "must be memory Parm");
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1675 return Type::get_zero_type(_type->basic_type());
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1676 }
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
1677 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 return _type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1680
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 //------------------------------match_edge-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 // Do we Match on this edge index or not? Match only the address.
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 uint LoadNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 return idx == MemNode::Address;
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 //--------------------------LoadBNode::Ideal--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // If the previous store is to the same address as this load,
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 // and the value stored was larger than a byte, replace this load
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // with the value stored truncated to a byte. If no truncation is
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 // needed, the replacement is done in LoadNode::Identity().
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 Node *LoadBNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 Node* mem = in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 Node* value = can_see_stored_value(mem,phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 if( value && !phase->type(value)->higher_equal( _type ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(24)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 return new (phase->C, 3) RShiftINode(result, phase->intcon(24));
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 // Identity call will handle the case where truncation is not needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 return LoadNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1704
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1705 //--------------------------LoadUBNode::Ideal-------------------------------------
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1706 //
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1707 // If the previous store is to the same address as this load,
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1708 // and the value stored was larger than a byte, replace this load
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1709 // with the value stored truncated to a byte. If no truncation is
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1710 // needed, the replacement is done in LoadNode::Identity().
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1711 //
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1712 Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) {
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1713 Node* mem = in(MemNode::Memory);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1714 Node* value = can_see_stored_value(mem, phase);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1715 if (value && !phase->type(value)->higher_equal(_type))
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1716 return new (phase->C, 3) AndINode(value, phase->intcon(0xFF));
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1717 // Identity call will handle the case where truncation is not needed.
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1718 return LoadNode::Ideal(phase, can_reshape);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1719 }
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 605
diff changeset
1720
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
1721 //--------------------------LoadUSNode::Ideal-------------------------------------
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // If the previous store is to the same address as this load,
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // and the value stored was larger than a char, replace this load
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // with the value stored truncated to a char. If no truncation is
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // needed, the replacement is done in LoadNode::Identity().
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 //
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 553
diff changeset
1728 Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 Node* mem = in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 Node* value = can_see_stored_value(mem,phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 if( value && !phase->type(value)->higher_equal( _type ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 return new (phase->C, 3) AndINode(value,phase->intcon(0xFFFF));
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // Identity call will handle the case where truncation is not needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 return LoadNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1736
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 //--------------------------LoadSNode::Ideal--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // If the previous store is to the same address as this load,
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 // and the value stored was larger than a short, replace this load
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 // with the value stored truncated to a short. If no truncation is
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 // needed, the replacement is done in LoadNode::Identity().
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 Node *LoadSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 Node* mem = in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 Node* value = can_see_stored_value(mem,phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 if( value && !phase->type(value)->higher_equal( _type ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(16)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 return new (phase->C, 3) RShiftINode(result, phase->intcon(16));
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // Identity call will handle the case where truncation is not needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 return LoadNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1754
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 //=============================================================================
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1756 //----------------------------LoadKlassNode::make------------------------------
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1757 // Polymorphic factory method:
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1758 Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) {
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1759 Compile* C = gvn.C;
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1760 Node *ctl = NULL;
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1761 // sanity check the alias category against the created node type
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1762 const TypeOopPtr *adr_type = adr->bottom_type()->isa_oopptr();
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1763 assert(adr_type != NULL, "expecting TypeOopPtr");
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1764 #ifdef _LP64
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1765 if (adr_type->is_ptr_to_narrowoop()) {
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
1766 Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop()));
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
1767 return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr());
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1768 }
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1769 #endif
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1770 assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 164
diff changeset
1771 return new (C, 3) LoadKlassNode(ctl, mem, adr, at, tk);
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1772 }
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1773
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 const Type *LoadKlassNode::Value( PhaseTransform *phase ) const {
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1776 return klass_value_common(phase);
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1777 }
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1778
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1779 const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 const Type *t1 = phase->type( in(MemNode::Memory) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 if (t1 == Type::TOP) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 Node *adr = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 const Type *t2 = phase->type( adr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 if (t2 == Type::TOP) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 const TypePtr *tp = t2->is_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 if (TypePtr::above_centerline(tp->ptr()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 tp->ptr() == TypePtr::Null) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1789
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 // Return a more precise klass, if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 const TypeInstPtr *tinst = tp->isa_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 if (tinst != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 ciInstanceKlass* ik = tinst->klass()->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 int offset = tinst->offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 if (ik == phase->C->env()->Class_klass()
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 && (offset == java_lang_Class::klass_offset_in_bytes() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 offset == java_lang_Class::array_klass_offset_in_bytes())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 // We are loading a special hidden field from a Class mirror object,
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 // the field which points to the VM's Klass metaobject.
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 ciType* t = tinst->java_mirror_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 // java_mirror_type returns non-null for compile-time Class constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 if (t != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 // constant oop => constant klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 if (offset == java_lang_Class::array_klass_offset_in_bytes()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 return TypeKlassPtr::make(ciArrayKlass::make(t));
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 if (!t->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 // a primitive Class (e.g., int.class) has NULL for a klass field
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 return TypePtr::NULL_PTR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 // (Folds up the 1st indirection in aClassConstant.getModifiers().)
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 return TypeKlassPtr::make(t->as_klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // non-constant mirror, so we can't tell what's going on
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 if( !ik->is_loaded() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 return _type; // Bail out if not loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 if (offset == oopDesc::klass_offset_in_bytes()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 if (tinst->klass_is_exact()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 return TypeKlassPtr::make(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 // See if we can become precise: no subklasses and no interface
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 // (Note: We need to support verified interfaces.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 if (!ik->is_interface() && !ik->has_subklass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 //assert(!UseExactTypes, "this code should be useless with exact types");
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 // Add a dependence; if any subclass added we need to recompile
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 if (!ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 // %%% should use stronger assert_unique_concrete_subtype instead
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 phase->C->dependencies()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 // Return precise klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 return TypeKlassPtr::make(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1834
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 // Return root of possible klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 return TypeKlassPtr::make(TypePtr::NotNull, ik, 0/*offset*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1839
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 // Check for loading klass from an array
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 const TypeAryPtr *tary = tp->isa_aryptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 if( tary != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 ciKlass *tary_klass = tary->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 if (tary_klass != NULL // can be NULL when at BOTTOM or TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 && tary->offset() == oopDesc::klass_offset_in_bytes()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 if (tary->klass_is_exact()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 return TypeKlassPtr::make(tary_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 ciArrayKlass *ak = tary->klass()->as_array_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // If the klass is an object array, we defer the question to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 // array component klass.
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 if( ak->is_obj_array_klass() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 assert( ak->is_loaded(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 ciKlass *base_k = ak->as_obj_array_klass()->base_element_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 if( base_k->is_loaded() && base_k->is_instance_klass() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 ciInstanceKlass* ik = base_k->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 // See if we can become precise: no subklasses and no interface
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 if (!ik->is_interface() && !ik->has_subklass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 //assert(!UseExactTypes, "this code should be useless with exact types");
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // Add a dependence; if any subclass added we need to recompile
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 if (!ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 phase->C->dependencies()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 // Return precise array klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 return TypeKlassPtr::make(ak);
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 return TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 } else { // Found a type-array?
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 //assert(!UseExactTypes, "this code should be useless with exact types");
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 assert( ak->is_type_array_klass(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 return TypeKlassPtr::make(ak); // These are always precise
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1876
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 // Check for loading klass from an array klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 const TypeKlassPtr *tkls = tp->isa_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 if (tkls != NULL && !StressReflectiveCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 ciKlass* klass = tkls->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 if( !klass->is_loaded() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 return _type; // Bail out if not loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 if( klass->is_obj_array_klass() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 (uint)tkls->offset() == objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 ciKlass* elem = klass->as_obj_array_klass()->element_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 // // Always returning precise element type is incorrect,
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 // // e.g., element type could be object and array may contain strings
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 // return TypeKlassPtr::make(TypePtr::Constant, elem, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1889
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 // The array's TypeKlassPtr was declared 'precise' or 'not precise'
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 // according to the element type's subclassing.
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 return TypeKlassPtr::make(tkls->ptr(), elem, 0/*offset*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 if( klass->is_instance_klass() && tkls->klass_is_exact() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 (uint)tkls->offset() == Klass::super_offset_in_bytes() + sizeof(oopDesc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 ciKlass* sup = klass->as_instance_klass()->super();
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 // The field is Klass::_super. Return its (constant) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 // (Folds up the 2nd indirection in aClassConstant.getSuperClass().)
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 return sup ? TypeKlassPtr::make(sup) : TypePtr::NULL_PTR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1902
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 // Bailout case
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 return LoadNode::Value(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1906
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 // To clean up reflective code, simplify k.java_mirror.as_klass to plain k.
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 // Also feed through the klass in Allocate(...klass...)._klass.
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 Node* LoadKlassNode::Identity( PhaseTransform *phase ) {
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1911 return klass_identity_common(phase);
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1912 }
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1913
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1914 Node* LoadNode::klass_identity_common(PhaseTransform *phase ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 Node* x = LoadNode::Identity(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 if (x != this) return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
1917
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 // Take apart the address into an oop and and offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 // Return 'this' if we cannot.
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 Node* adr = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 intptr_t offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 if (base == NULL) return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 const TypeOopPtr* toop = phase->type(adr)->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 if (toop == NULL) return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1926
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 // We can fetch the klass directly through an AllocateNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 // This works even if the klass is not constant (clone or newArray).
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 if (offset == oopDesc::klass_offset_in_bytes()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 Node* allocated_klass = AllocateNode::Ideal_klass(base, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 if (allocated_klass != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 return allocated_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1935
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 // Simplify k.java_mirror.as_klass to plain k, where k is a klassOop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 // Simplify ak.component_mirror.array_klass to plain ak, ak an arrayKlass.
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 // See inline_native_Class_query for occurrences of these patterns.
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 // Java Example: x.getClass().isAssignableFrom(y)
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 // Java Example: Array.newInstance(x.getClass().getComponentType(), n)
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 // This improves reflective code, often making the Class
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 // mirror go completely dead. (Current exception: Class
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 // mirrors may appear in debug info, but we could clean them out by
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 // introducing a new debug info operator for klassOop.java_mirror).
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 && (offset == java_lang_Class::klass_offset_in_bytes() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 offset == java_lang_Class::array_klass_offset_in_bytes())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 // We are loading a special hidden field from a Class mirror,
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // the field which points to its Klass or arrayKlass metaobject.
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 if (base->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 Node* adr2 = base->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 if (tkls != NULL && !tkls->empty()
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 && (tkls->klass()->is_instance_klass() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 tkls->klass()->is_array_klass())
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 && adr2->is_AddP()
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 int mirror_field = Klass::java_mirror_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 if (offset == java_lang_Class::array_klass_offset_in_bytes()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 mirror_field = in_bytes(arrayKlass::component_mirror_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 if (tkls->offset() == mirror_field + (int)sizeof(oopDesc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 return adr2->in(AddPNode::Base);
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1969
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1972
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1973
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1974 //------------------------------Value------------------------------------------
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1975 const Type *LoadNKlassNode::Value( PhaseTransform *phase ) const {
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1976 const Type *t = klass_value_common(phase);
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
1977 if (t == Type::TOP)
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
1978 return t;
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
1979
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
1980 return t->make_narrowoop();
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1981 }
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1982
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1983 //------------------------------Identity---------------------------------------
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1984 // To clean up reflective code, simplify k.java_mirror.as_klass to narrow k.
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1985 // Also feed through the klass in Allocate(...klass...)._klass.
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1986 Node* LoadNKlassNode::Identity( PhaseTransform *phase ) {
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1987 Node *x = klass_identity_common(phase);
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1988
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1989 const Type *t = phase->type( x );
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1990 if( t == Type::TOP ) return x;
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1991 if( t->isa_narrowoop()) return x;
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1992
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
1993 return phase->transform(new (phase->C, 2) EncodePNode(x, t->make_narrowoop()));
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1994 }
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
1995
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 //------------------------------Value-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 const Type *LoadRangeNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 const Type *t1 = phase->type( in(MemNode::Memory) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 Node *adr = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 const Type *t2 = phase->type( adr );
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 const TypePtr *tp = t2->is_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 if (TypePtr::above_centerline(tp->ptr())) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 const TypeAryPtr *tap = tp->isa_aryptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 if( !tap ) return _type;
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 return tap->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2010
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2011 //-------------------------------Ideal---------------------------------------
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2012 // Feed through the length in AllocateArray(...length...)._length.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2013 Node *LoadRangeNode::Ideal(PhaseGVN *phase, bool can_reshape) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2014 Node* p = MemNode::Ideal_common(phase, can_reshape);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2015 if (p) return (p == NodeSentinel) ? NULL : p;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2016
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2017 // Take apart the address into an oop and and offset.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2018 // Return 'this' if we cannot.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2019 Node* adr = in(MemNode::Address);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2020 intptr_t offset = 0;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2021 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2022 if (base == NULL) return NULL;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2023 const TypeAryPtr* tary = phase->type(adr)->isa_aryptr();
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2024 if (tary == NULL) return NULL;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2025
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2026 // We can fetch the length directly through an AllocateArrayNode.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2027 // This works even if the length is not constant (clone or newArray).
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2028 if (offset == arrayOopDesc::length_offset_in_bytes()) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2029 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(base, phase);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2030 if (alloc != NULL) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2031 Node* allocated_length = alloc->Ideal_length();
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2032 Node* len = alloc->make_ideal_length(tary, phase);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2033 if (allocated_length != len) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2034 // New CastII improves on this.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2035 return len;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2036 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2037 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2038 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2039
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2040 return NULL;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2041 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2042
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 // Feed through the length in AllocateArray(...length...)._length.
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 Node* LoadRangeNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 Node* x = LoadINode::Identity(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 if (x != this) return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
2048
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 // Take apart the address into an oop and and offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 // Return 'this' if we cannot.
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 Node* adr = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 intptr_t offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 if (base == NULL) return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 const TypeAryPtr* tary = phase->type(adr)->isa_aryptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 if (tary == NULL) return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
2057
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 // We can fetch the length directly through an AllocateArrayNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 // This works even if the length is not constant (clone or newArray).
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 if (offset == arrayOopDesc::length_offset_in_bytes()) {
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2061 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(base, phase);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2062 if (alloc != NULL) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2063 Node* allocated_length = alloc->Ideal_length();
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2064 // Do not allow make_ideal_length to allocate a CastII node.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2065 Node* len = alloc->make_ideal_length(tary, phase, false);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2066 if (allocated_length == len) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2067 // Return allocated_length only if it would not be improved by a CastII.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2068 return allocated_length;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2069 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2072
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
2074
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 }
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 305
diff changeset
2076
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 //---------------------------StoreNode::make-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // Polymorphic factory method:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2080 StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt ) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2081 Compile* C = gvn.C;
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
2082 assert( C->get_alias_index(adr_type) != Compile::AliasIdxRaw ||
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
2083 ctl != NULL, "raw memory operations should have control edge");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2084
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 switch (bt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 case T_BYTE: return new (C, 4) StoreBNode(ctl, mem, adr, adr_type, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 case T_INT: return new (C, 4) StoreINode(ctl, mem, adr, adr_type, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 case T_SHORT: return new (C, 4) StoreCNode(ctl, mem, adr, adr_type, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 case T_LONG: return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 case T_FLOAT: return new (C, 4) StoreFNode(ctl, mem, adr, adr_type, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 case T_DOUBLE: return new (C, 4) StoreDNode(ctl, mem, adr, adr_type, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 case T_ADDRESS:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2095 case T_OBJECT:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2096 #ifdef _LP64
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 155
diff changeset
2097 if (adr->bottom_type()->is_ptr_to_narrowoop() ||
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2098 (UseCompressedOops && val->bottom_type()->isa_klassptr() &&
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2099 adr->bottom_type()->isa_rawptr())) {
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
2100 val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop()));
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
2101 return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2102 } else
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2103 #endif
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
2104 {
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
2105 return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val);
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 193
diff changeset
2106 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 return (StoreNode*)NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2111
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 bool require_atomic = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val, require_atomic);
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 //--------------------------bottom_type----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 const Type *StoreNode::bottom_type() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 return Type::MEMORY;
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2122
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 //------------------------------hash-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 uint StoreNode::hash() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 // unroll addition of interesting fields
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 //return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address) + (uintptr_t)in(ValueIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2127
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 // Since they are not commoned, do not hash them:
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 return NO_HASH;
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2131
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 // Change back-to-back Store(, p, x) -> Store(m, p, y) to Store(m, p, x).
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 // When a store immediately follows a relevant allocation/initialization,
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 // try to capture it into the initialization, or hoist it above.
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 Node* p = MemNode::Ideal_common(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 if (p) return (p == NodeSentinel) ? NULL : p;
a61af66fc99e Initial load
duke
parents:
diff changeset
2139
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 Node* mem = in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 Node* address = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
2142
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // Back-to-back stores to same address? Fold em up.
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 // Generally unsafe if I have intervening uses...
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 if (mem->is_Store() && phase->eqv_uncast(mem->in(MemNode::Address), address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 // Looking at a dead closed cycle of memory?
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal");
a61af66fc99e Initial load
duke
parents:
diff changeset
2148
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 assert(Opcode() == mem->Opcode() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw,
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 "no mismatched stores, except on raw memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
2152
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 if (mem->outcnt() == 1 && // check for intervening uses
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 mem->as_Store()->memory_size() <= this->memory_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 // If anybody other than 'this' uses 'mem', we cannot fold 'mem' away.
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 // For example, 'mem' might be the final state at a conditional return.
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 // Or, 'mem' might be used by some node which is live at the same time
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 // 'this' is live, which might be unschedulable. So, require exactly
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 // ONE user, the 'this' store, until such time as we clone 'mem' for
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 // each of 'mem's uses (thus making the exactly-1-user-rule hold true).
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 if (can_reshape) { // (%%% is this an anachronism?)
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 set_req_X(MemNode::Memory, mem->in(MemNode::Memory),
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 phase->is_IterGVN());
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 // It's OK to do this in the parser, since DU info is always accurate,
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // and the parser always refers to nodes via SafePointNode maps.
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 set_req(MemNode::Memory, mem->in(MemNode::Memory));
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2172
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // Capture an unaliased, unconditional, simple store into an initializer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 // Or, if it is independent of the allocation, hoist it above the allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 if (ReduceFieldZeroing && /*can_reshape &&*/
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 mem->is_Proj() && mem->in(0)->is_Initialize()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 InitializeNode* init = mem->in(0)->as_Initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 intptr_t offset = init->can_capture_store(this, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 if (offset > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 Node* moved = init->capture_store(this, offset, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 // If the InitializeNode captured me, it made a raw copy of me,
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 // and I need to disappear.
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 if (moved != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // %%% hack to ensure that Ideal returns a new node:
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 mem = MergeMemNode::make(phase->C, mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 return mem; // fold me away
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2190
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 return NULL; // No further progress
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2193
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 //------------------------------Value-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 const Type *StoreNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 const Type *t1 = phase->type( in(MemNode::Memory) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 const Type *t2 = phase->type( in(MemNode::Address) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 const Type *t3 = phase->type( in(MemNode::ValueIn) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 if( t3 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 return Type::MEMORY;
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2205
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 // Remove redundant stores:
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 // Store(m, p, Load(m, p)) changes to m.
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 // Store(, p, x) -> Store(m, p, x) changes to Store(m, p, x).
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 Node *StoreNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 Node* mem = in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 Node* adr = in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 Node* val = in(MemNode::ValueIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2214
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 // Load then Store? Then the Store is useless
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 if (val->is_Load() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 phase->eqv_uncast( val->in(MemNode::Address), adr ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 phase->eqv_uncast( val->in(MemNode::Memory ), mem ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 val->as_Load()->store_Opcode() == Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 return mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2222
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 // Two stores in a row of the same value?
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 if (mem->is_Store() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 phase->eqv_uncast( mem->in(MemNode::Address), adr ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 phase->eqv_uncast( mem->in(MemNode::ValueIn), val ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 mem->Opcode() == Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 return mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2230
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 // Store of zero anywhere into a freshly-allocated object?
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 // Then the store is useless.
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 // (It must already have been captured by the InitializeNode.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 if (ReduceFieldZeroing && phase->type(val)->is_zero_type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // a newly allocated object is already all-zeroes everywhere
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 if (mem->is_Proj() && mem->in(0)->is_Allocate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 return mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2239
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 // the store may also apply to zero-bits in an earlier object
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 Node* prev_mem = find_previous_store(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 // Steps (a), (b): Walk past independent stores to find an exact match.
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 if (prev_mem != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 Node* prev_val = can_see_stored_value(prev_mem, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 if (prev_val != NULL && phase->eqv(prev_val, val)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 // prev_val and val might differ by a cast; it would be good
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 // to keep the more informative of the two.
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 return mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2252
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2255
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 //------------------------------match_edge-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 // Do we Match on this edge index or not? Match only memory & value
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 uint StoreNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 return idx == MemNode::Address || idx == MemNode::ValueIn;
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2261
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 //------------------------------cmp--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 // Do not common stores up together. They generally have to be split
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // back up anyways, so do not bother.
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 uint StoreNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 return (&n == this); // Always fail except on self
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2268
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 //------------------------------Ideal_masked_input-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 // Check for a useless mask before a partial-word store
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 // (StoreB ... (AndI valIn conIa) )
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 // If (conIa & mask == mask) this simplifies to
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 // (StoreB ... (valIn) )
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 Node *StoreNode::Ideal_masked_input(PhaseGVN *phase, uint mask) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 Node *val = in(MemNode::ValueIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 if( val->Opcode() == Op_AndI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 const TypeInt *t = phase->type( val->in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 if( t && t->is_con() && (t->get_con() & mask) == mask ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 set_req(MemNode::ValueIn, val->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2285
a61af66fc99e Initial load
duke
parents:
diff changeset
2286
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 //------------------------------Ideal_sign_extended_input----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 // Check for useless sign-extension before a partial-word store
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // (StoreB ... (RShiftI _ (LShiftI _ valIn conIL ) conIR) )
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // If (conIL == conIR && conIR <= num_bits) this simplifies to
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 // (StoreB ... (valIn) )
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 Node *StoreNode::Ideal_sign_extended_input(PhaseGVN *phase, int num_bits) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 Node *val = in(MemNode::ValueIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 if( val->Opcode() == Op_RShiftI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 const TypeInt *t = phase->type( val->in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 if( t && t->is_con() && (t->get_con() <= num_bits) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 Node *shl = val->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 if( shl->Opcode() == Op_LShiftI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 const TypeInt *t2 = phase->type( shl->in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 if( t2 && t2->is_con() && (t2->get_con() == t->get_con()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 set_req(MemNode::ValueIn, shl->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2309
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 //------------------------------value_never_loaded-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 // Determine whether there are any possible loads of the value stored.
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 // For simplicity, we actually check if there are any loads from the
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 // address stored to, not just for loads of the value stored by this node.
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 bool StoreNode::value_never_loaded( PhaseTransform *phase) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 Node *adr = in(Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 if (adr_oop == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 return false;
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 221
diff changeset
2320 if (!adr_oop->is_known_instance_field())
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 return false; // if not a distinct instance, there may be aliases of the address
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 Node *use = adr->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 int opc = use->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 if (use->is_Load() || use->is_LoadStore()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2331
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 // If the store is from an AND mask that leaves the low bits untouched, then
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // we can skip the AND operation. If the store is from a sign-extension
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 // (a left shift, then right shift) we can skip both.
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 Node *StoreBNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 Node *progress = StoreNode::Ideal_masked_input(phase, 0xFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 if( progress != NULL ) return progress;
a61af66fc99e Initial load
duke
parents:
diff changeset
2340
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 progress = StoreNode::Ideal_sign_extended_input(phase, 24);
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 if( progress != NULL ) return progress;
a61af66fc99e Initial load
duke
parents:
diff changeset
2343
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 // Finally check the default case
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 return StoreNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2347
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 // If the store is from an AND mask that leaves the low bits untouched, then
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 // we can skip the AND operation
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 Node *StoreCNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 Node *progress = StoreNode::Ideal_masked_input(phase, 0xFFFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 if( progress != NULL ) return progress;
a61af66fc99e Initial load
duke
parents:
diff changeset
2355
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 progress = StoreNode::Ideal_sign_extended_input(phase, 16);
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 if( progress != NULL ) return progress;
a61af66fc99e Initial load
duke
parents:
diff changeset
2358
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 // Finally check the default case
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 return StoreNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 Node *StoreCMNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 // No need to card mark when storing a null ptr
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 Node* my_store = in(MemNode::OopStore);
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 if (my_store->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 const Type *t1 = phase->type( my_store->in(MemNode::ValueIn) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 if( t1 == TypePtr::NULL_PTR ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 return in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2376
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2377 //=============================================================================
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2378 //------------------------------Ideal---------------------------------------
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2379 Node *StoreCMNode::Ideal(PhaseGVN *phase, bool can_reshape){
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2380 Node* progress = StoreNode::Ideal(phase, can_reshape);
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2381 if (progress != NULL) return progress;
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2382
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2383 Node* my_store = in(MemNode::OopStore);
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2384 if (my_store->is_MergeMem()) {
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2385 Node* mem = my_store->as_MergeMem()->memory_at(oop_alias_idx());
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2386 set_req(MemNode::OopStore, mem);
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2387 return this;
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2388 }
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2389
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2390 return NULL;
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2391 }
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 708
diff changeset
2392
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 //------------------------------Value-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 const Type *StoreCMNode::Value( PhaseTransform *phase ) const {
43
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2395 // Either input is TOP ==> the result is TOP
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2396 const Type *t = phase->type( in(MemNode::Memory) );
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2397 if( t == Type::TOP ) return Type::TOP;
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2398 t = phase->type( in(MemNode::Address) );
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2399 if( t == Type::TOP ) return Type::TOP;
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2400 t = phase->type( in(MemNode::ValueIn) );
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2401 if( t == Type::TOP ) return Type::TOP;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 // If extra input is TOP ==> the result is TOP
43
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2403 t = phase->type( in(MemNode::OopStore) );
d821d920b465 6623167: C2 crashed in StoreCMNode::Value
kvn
parents: 36
diff changeset
2404 if( t == Type::TOP ) return Type::TOP;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2405
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 return StoreNode::Value( phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2408
a61af66fc99e Initial load
duke
parents:
diff changeset
2409
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 //----------------------------------SCMemProjNode------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 const Type * SCMemProjNode::Value( PhaseTransform *phase ) const
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 return bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2416
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex ) : Node(5) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 init_req(MemNode::Control, c );
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 init_req(MemNode::Memory , mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 init_req(MemNode::Address, adr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 init_req(MemNode::ValueIn, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 init_req( ExpectedIn, ex );
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 init_class_id(Class_LoadStore);
a61af66fc99e Initial load
duke
parents:
diff changeset
2425
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2427
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 //-------------------------------adr_type--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 // Do we Match on this edge index or not? Do not match memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 const TypePtr* ClearArrayNode::adr_type() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 Node *adr = in(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 return MemNode::calculate_adr_type(adr->bottom_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2435
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 //------------------------------match_edge-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 // Do we Match on this edge index or not? Do not match memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 uint ClearArrayNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 return idx > 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2441
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 // Clearing a zero length array does nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 Node *ClearArrayNode::Identity( PhaseTransform *phase ) {
68
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2445 return phase->type(in(2))->higher_equal(TypeX::ZERO) ? in(1) : this;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2447
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 //------------------------------Idealize---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 // Clearing a short array is faster with stores
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 const int unit = BytesPerLong;
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 const TypeX* t = phase->type(in(2))->isa_intptr_t();
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 if (!t) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 if (!t->is_con()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 intptr_t raw_count = t->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 intptr_t size = raw_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 if (!Matcher::init_array_count_is_in_bytes) size *= unit;
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 // Clearing nothing uses the Identity call.
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 // Negative clears are possible on dead ClearArrays
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 // (see jck test stmt114.stmt11402.val).
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 if (size <= 0 || size % unit != 0) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 intptr_t count = size / unit;
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 // Length too long; use fast hardware clear
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 if (size > Matcher::init_array_short_size) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 Node *mem = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 if( phase->type(mem)==Type::TOP ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 Node *adr = in(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 const Type* at = phase->type(adr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 if( at==Type::TOP ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 const TypePtr* atp = at->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 // adjust atp to be the correct array element address type
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 if (atp == NULL) atp = TypePtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 else atp = atp->add_offset(Type::OffsetBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 // Get base for derived pointer purposes
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 if( adr->Opcode() != Op_AddP ) Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 Node *base = adr->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2477
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 Node *zero = phase->makecon(TypeLong::ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 Node *off = phase->MakeConX(BytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero);
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 count--;
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 while( count-- ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 mem = phase->transform(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 adr = phase->transform(new (phase->C, 4) AddPNode(base,adr,off));
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero);
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 return mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2489
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2490 //----------------------------step_through----------------------------------
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2491 // Return allocation input memory edge if it is different instance
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2492 // or itself if it is the one we are looking for.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2493 bool ClearArrayNode::step_through(Node** np, uint instance_id, PhaseTransform* phase) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2494 Node* n = *np;
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2495 assert(n->is_ClearArray(), "sanity");
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2496 intptr_t offset;
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2497 AllocateNode* alloc = AllocateNode::Ideal_allocation(n->in(3), phase, offset);
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2498 // This method is called only before Allocate nodes are expanded during
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2499 // macro nodes expansion. Before that ClearArray nodes are only generated
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2500 // in LibraryCallKit::generate_arraycopy() which follows allocations.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2501 assert(alloc != NULL, "should have allocation");
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2502 if (alloc->_idx == instance_id) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2503 // Can not bypass initialization of the instance we are looking for.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2504 return false;
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2505 }
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2506 // Otherwise skip it.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2507 InitializeNode* init = alloc->initialization();
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2508 if (init != NULL)
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2509 *np = init->in(TypeFunc::Memory);
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2510 else
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2511 *np = alloc->in(TypeFunc::Memory);
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2512 return true;
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2513 }
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2514
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 //----------------------------clear_memory-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 // Generate code to initialize object storage to zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 intptr_t start_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 Node* end_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 Compile* C = phase->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 intptr_t offset = start_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2523
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 int unit = BytesPerLong;
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 if ((offset % unit) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 adr = phase->transform(adr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 const TypePtr* atp = TypeRawPtr::BOTTOM;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2529 mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 mem = phase->transform(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 offset += BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 assert((offset % unit) == 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2534
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 // Initialize the remaining stuff, if any, with a ClearArray.
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 return clear_memory(ctl, mem, dest, phase->MakeConX(offset), end_offset, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2538
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 Node* start_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 Node* end_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 PhaseGVN* phase) {
68
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2543 if (start_offset == end_offset) {
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2544 // nothing to do
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2545 return mem;
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2546 }
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2547
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 Compile* C = phase->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 int unit = BytesPerLong;
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 Node* zbase = start_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 Node* zend = end_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2552
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 // Scale to the unit required by the CPU:
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 if (!Matcher::init_array_count_is_in_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 Node* shift = phase->intcon(exact_log2(unit));
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 zbase = phase->transform( new(C,3) URShiftXNode(zbase, shift) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 zend = phase->transform( new(C,3) URShiftXNode(zend, shift) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2559
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 Node* zsize = phase->transform( new(C,3) SubXNode(zend, zbase) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2562
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 // Bulk clear double-words
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 Node* adr = phase->transform( new(C,4) AddPNode(dest, dest, start_offset) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 mem = new (C, 4) ClearArrayNode(ctl, mem, zsize, adr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 return phase->transform(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2568
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 intptr_t start_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 intptr_t end_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 PhaseGVN* phase) {
68
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2573 if (start_offset == end_offset) {
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2574 // nothing to do
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2575 return mem;
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2576 }
daf38130e60d 6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents: 64
diff changeset
2577
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 Compile* C = phase->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 assert((end_offset % BytesPerInt) == 0, "odd end offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 intptr_t done_offset = end_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 if ((done_offset % BytesPerLong) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 done_offset -= BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 if (done_offset > start_offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 mem = clear_memory(ctl, mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 start_offset, phase->MakeConX(done_offset), phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 if (done_offset < end_offset) { // emit the final 32-bit store
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(done_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 adr = phase->transform(adr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 const TypePtr* atp = TypeRawPtr::BOTTOM;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
2592 mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 mem = phase->transform(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 done_offset += BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 assert(done_offset == end_offset, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 return mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2599
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 // Do we match on this edge? No memory edges
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 uint StrCompNode::match_edge(uint idx) const {
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2603 return idx == 2 || idx == 3; // StrComp (Binary str1 cnt1) (Binary str2 cnt2)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2605
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 // Return a node which is more "ideal" than the current node. Strip out
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 // control copies
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 Node *StrCompNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 return remove_dead_region(phase, can_reshape) ? this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2612
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2613 //=============================================================================
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2614 // Do we match on this edge? No memory edges
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2615 uint StrEqualsNode::match_edge(uint idx) const {
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2616 return idx == 2 || idx == 3; // StrEquals (Binary str1 str2) cnt
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2617 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2618
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2619 //------------------------------Ideal------------------------------------------
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2620 // Return a node which is more "ideal" than the current node. Strip out
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2621 // control copies
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2622 Node *StrEqualsNode::Ideal(PhaseGVN *phase, bool can_reshape){
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2623 return remove_dead_region(phase, can_reshape) ? this : NULL;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2624 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2625
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2626 //=============================================================================
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2627 // Do we match on this edge? No memory edges
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2628 uint StrIndexOfNode::match_edge(uint idx) const {
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2629 return idx == 2 || idx == 3; // StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2630 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2631
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2632 //------------------------------Ideal------------------------------------------
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2633 // Return a node which is more "ideal" than the current node. Strip out
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2634 // control copies
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2635 Node *StrIndexOfNode::Ideal(PhaseGVN *phase, bool can_reshape){
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2636 return remove_dead_region(phase, can_reshape) ? this : NULL;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2637 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 628
diff changeset
2638
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2639 //=============================================================================
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2640 // Do we match on this edge? No memory edges
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2641 uint AryEqNode::match_edge(uint idx) const {
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2642 return idx == 2 || idx == 3; // StrEquals ary1 ary2
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 985
diff changeset
2643 }
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
2644 //------------------------------Ideal------------------------------------------
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
2645 // Return a node which is more "ideal" than the current node. Strip out
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
2646 // control copies
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
2647 Node *AryEqNode::Ideal(PhaseGVN *phase, bool can_reshape){
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
2648 return remove_dead_region(phase, can_reshape) ? this : NULL;
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
2649 }
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 168
diff changeset
2650
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 MemBarNode::MemBarNode(Compile* C, int alias_idx, Node* precedent)
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 : MultiNode(TypeFunc::Parms + (precedent == NULL? 0: 1)),
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 _adr_type(C->get_adr_type(alias_idx))
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 init_class_id(Class_MemBar);
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 Node* top = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 init_req(TypeFunc::I_O,top);
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 init_req(TypeFunc::FramePtr,top);
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 init_req(TypeFunc::ReturnAdr,top);
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 if (precedent != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 init_req(TypeFunc::Parms, precedent);
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2664
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 //------------------------------cmp--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 uint MemBarNode::hash() const { return NO_HASH; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 uint MemBarNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 return (&n == this); // Always fail except on self
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2670
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 //------------------------------make-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 int len = Precedent + (pn == NULL? 0: 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 switch (opcode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 case Op_MemBarAcquire: return new(C, len) MemBarAcquireNode(C, atp, pn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 case Op_MemBarRelease: return new(C, len) MemBarReleaseNode(C, atp, pn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 case Op_MemBarVolatile: return new(C, len) MemBarVolatileNode(C, atp, pn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 case Op_MemBarCPUOrder: return new(C, len) MemBarCPUOrderNode(C, atp, pn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 case Op_Initialize: return new(C, len) InitializeNode(C, atp, pn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 default: ShouldNotReachHere(); return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2683
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 // Return a node which is more "ideal" than the current node. Strip out
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 // control copies
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2688 if (remove_dead_region(phase, can_reshape)) return this;
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2689
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2690 // Eliminate volatile MemBars for scalar replaced objects.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2691 if (can_reshape && req() == (Precedent+1) &&
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2692 (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2693 // Volatile field loads and stores.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2694 Node* my_mem = in(MemBarNode::Precedent);
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2695 if (my_mem != NULL && my_mem->is_Mem()) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2696 const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2697 // Check for scalar replaced object reference.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2698 if( t_oop != NULL && t_oop->is_known_instance_field() &&
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2699 t_oop->offset() != Type::OffsetBot &&
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2700 t_oop->offset() != Type::OffsetTop) {
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2701 // Replace MemBar projections by its inputs.
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2702 PhaseIterGVN* igvn = phase->is_IterGVN();
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2703 igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2704 igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2705 // Must return either the original node (now dead) or a new node
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2706 // (Do not return a top here, since that would break the uniqueness of top.)
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2707 return new (phase->C, 1) ConINode(TypeInt::ZERO);
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2708 }
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2709 }
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2710 }
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
2711 return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2713
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 const Type *MemBarNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 if( !in(0) ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 if( phase->type(in(0)) == Type::TOP )
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 return TypeTuple::MEMBAR;
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2721
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 //------------------------------match------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 // Construct projections for memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 Node *MemBarNode::match( const ProjNode *proj, const Matcher *m ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 switch (proj->_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 case TypeFunc::Control:
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 case TypeFunc::Memory:
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 return new (m->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2733
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 //===========================InitializeNode====================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 // SUMMARY:
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 // This node acts as a memory barrier on raw memory, after some raw stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 // The 'cooked' oop value feeds from the Initialize, not the Allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 // The Initialize can 'capture' suitably constrained stores as raw inits.
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 // It can coalesce related raw stores into larger units (called 'tiles').
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 // It can avoid zeroing new storage for memory units which have raw inits.
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 // At macro-expansion, it is marked 'complete', and does not optimize further.
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 // EXAMPLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 // The object 'new short[2]' occupies 16 bytes in a 32-bit machine.
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 // ctl = incoming control; mem* = incoming memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 // (Note: A star * on a memory edge denotes I/O and other standard edges.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 // First allocate uninitialized memory and fill in the header:
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 // alloc = (Allocate ctl mem* 16 #short[].klass ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 // ctl := alloc.Control; mem* := alloc.Memory*
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 // rawmem = alloc.Memory; rawoop = alloc.RawAddress
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 // Then initialize to zero the non-header parts of the raw memory block:
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 // init = (Initialize alloc.Control alloc.Memory* alloc.RawAddress)
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 // ctl := init.Control; mem.SLICE(#short[*]) := init.Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 // After the initialize node executes, the object is ready for service:
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 // oop := (CheckCastPP init.Control alloc.RawAddress #short[])
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 // Suppose its body is immediately initialized as {1,2}:
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 // store1 = (StoreC init.Control init.Memory (+ oop 12) 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 // store2 = (StoreC init.Control store1 (+ oop 14) 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 // mem.SLICE(#short[*]) := store2
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 // DETAILS:
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 // An InitializeNode collects and isolates object initialization after
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 // an AllocateNode and before the next possible safepoint. As a
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 // memory barrier (MemBarNode), it keeps critical stores from drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 // down past any safepoint or any publication of the allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 // Before this barrier, a newly-allocated object may have uninitialized bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 // After this barrier, it may be treated as a real oop, and GC is allowed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 // The semantics of the InitializeNode include an implicit zeroing of
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 // the new object from object header to the end of the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 // (The object header and end are determined by the AllocateNode.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 // Certain stores may be added as direct inputs to the InitializeNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 // These stores must update raw memory, and they must be to addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 // derived from the raw address produced by AllocateNode, and with
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 // a constant offset. They must be ordered by increasing offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 // The first one is at in(RawStores), the last at in(req()-1).
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 // Unlike most memory operations, they are not linked in a chain,
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 // but are displayed in parallel as users of the rawmem output of
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 // the allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 // (See comments in InitializeNode::capture_store, which continue
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 // the example given above.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 // When the associated Allocate is macro-expanded, the InitializeNode
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 // may be rewritten to optimize collected stores. A ClearArrayNode
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 // may also be created at that point to represent any required zeroing.
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 // The InitializeNode is then marked 'complete', prohibiting further
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 // capturing of nearby memory operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 // During macro-expansion, all captured initializations which store
605
98cb887364d3 6810672: Comment typos
twisti
parents: 583
diff changeset
2792 // constant values of 32 bits or smaller are coalesced (if advantageous)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 // into larger 'tiles' 32 or 64 bits. This allows an object to be
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 // initialized in fewer memory operations. Memory words which are
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 // covered by neither tiles nor non-constant stores are pre-zeroed
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 // by explicit stores of zero. (The code shape happens to do all
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 // zeroing first, then all other stores, with both sequences occurring
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 // in order of ascending offsets.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 // Alternatively, code may be inserted between an AllocateNode and its
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 // InitializeNode, to perform arbitrary initialization of the new object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 // E.g., the object copying intrinsics insert complex data transfers here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 // The initialization must then be marked as 'complete' disable the
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 // built-in zeroing semantics and the collection of initializing stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 // While an InitializeNode is incomplete, reads from the memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 // produced by it are optimizable if they match the control edge and
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 // new oop address associated with the allocation/initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 // They return a stored value (if the offset matches) or else zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 // A write to the memory state, if it matches control and address,
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 // and if it is to a constant offset, may be 'captured' by the
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 // InitializeNode. It is cloned as a raw memory operation and rewired
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 // inside the initialization, to the raw oop produced by the allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 // Operations on addresses which are provably distinct (e.g., to
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 // other AllocateNodes) are allowed to bypass the initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 // The effect of all this is to consolidate object initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 // (both arrays and non-arrays, both piecewise and bulk) into a
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 // single location, where it can be optimized as a unit.
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 // Only stores with an offset less than TrackedInitializationLimit words
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 // will be considered for capture by an InitializeNode. This puts a
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 // reasonable limit on the complexity of optimized initializations.
a61af66fc99e Initial load
duke
parents:
diff changeset
2824
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 //---------------------------InitializeNode------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 InitializeNode::InitializeNode(Compile* C, int adr_type, Node* rawoop)
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 : _is_complete(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 MemBarNode(C, adr_type, rawoop)
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 init_class_id(Class_Initialize);
a61af66fc99e Initial load
duke
parents:
diff changeset
2831
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 assert(adr_type == Compile::AliasIdxRaw, "only valid atp");
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 assert(in(RawAddress) == rawoop, "proper init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 // Note: allocation() can be NULL, for secondary initialization barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2836
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 // Since this node is not matched, it will be processed by the
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 // register allocator. Declare that there are no constraints
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 // on the allocation of the RawAddress edge.
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 const RegMask &InitializeNode::in_RegMask(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 // This edge should be set to top, by the set_complete. But be conservative.
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 if (idx == InitializeNode::RawAddress)
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 return *(Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2846
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 Node* InitializeNode::memory(uint alias_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 Node* mem = in(Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 if (mem->is_MergeMem()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 return mem->as_MergeMem()->memory_at(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 // incoming raw memory is not split
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 return mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2856
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 bool InitializeNode::is_non_zero() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 if (is_complete()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 remove_extra_zeroes();
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 return (req() > RawStores);
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2862
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 void InitializeNode::set_complete(PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 assert(!is_complete(), "caller responsibility");
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 _is_complete = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2866
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 // After this node is complete, it contains a bunch of
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 // raw-memory initializations. There is no need for
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 // it to have anything to do with non-raw memory effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 // Therefore, tell all non-raw users to re-optimize themselves,
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 // after skipping the memory effects of this initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 PhaseIterGVN* igvn = phase->is_IterGVN();
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 if (igvn) igvn->add_users_to_worklist(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2875
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 // convenience function
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 // return false if the init contains any stores already
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 bool AllocateNode::maybe_set_complete(PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 InitializeNode* init = initialization();
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 if (init == NULL || init->is_complete()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 init->remove_extra_zeroes();
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 // for now, if this allocation has already collected any inits, bail:
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 if (init->is_non_zero()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 init->set_complete(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2887
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 void InitializeNode::remove_extra_zeroes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 if (req() == RawStores) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 Node* zmem = zero_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 uint fill = RawStores;
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 for (uint i = fill; i < req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 Node* n = in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 if (n->is_top() || n == zmem) continue; // skip
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 if (fill < i) set_req(fill, n); // compact
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 ++fill;
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 // delete any empty spaces created:
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 while (fill < req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 del_req(fill);
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2903
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 // Helper for remembering which stores go with which offsets.
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 intptr_t InitializeNode::get_store_offset(Node* st, PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 if (!st->is_Store()) return -1; // can happen to dead code via subsume_node
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 intptr_t offset = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 Node* base = AddPNode::Ideal_base_and_offset(st->in(MemNode::Address),
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 phase, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 if (base == NULL) return -1; // something is dead,
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 if (offset < 0) return -1; // dead, dead
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 return offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2914
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 // Helper for proving that an initialization expression is
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 // "simple enough" to be folded into an object initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 // Attempts to prove that a store's initial value 'n' can be captured
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 // within the initialization without creating a vicious cycle, such as:
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 // { Foo p = new Foo(); p.next = p; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 // True for constants and parameters and small combinations thereof.
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 bool InitializeNode::detect_init_independence(Node* n,
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 bool st_is_pinned,
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 int& count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 if (n == NULL) return true; // (can this really happen?)
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 if (n->is_Proj()) n = n->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 if (n == this) return false; // found a cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 if (n->is_Con()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 if (n->is_Start()) return true; // params, etc., are OK
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 if (n->is_Root()) return true; // even better
a61af66fc99e Initial load
duke
parents:
diff changeset
2930
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 Node* ctl = n->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 if (ctl != NULL && !ctl->is_top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 if (ctl->is_Proj()) ctl = ctl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 if (ctl == this) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2935
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 // If we already know that the enclosing memory op is pinned right after
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 // the init, then any control flow that the store has picked up
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 // must have preceded the init, or else be equal to the init.
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 // Even after loop optimizations (which might change control edges)
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // a store is never pinned *before* the availability of its inputs.
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
2941 if (!MemNode::all_controls_dominate(n, this))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 return false; // failed to prove a good control
a61af66fc99e Initial load
duke
parents:
diff changeset
2943
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2945
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 // Check data edges for possible dependencies on 'this'.
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 if ((count += 1) > 20) return false; // complexity limit
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 for (uint i = 1; i < n->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 Node* m = n->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 if (m == NULL || m == n || m->is_top()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 uint first_i = n->find_edge(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 if (i != first_i) continue; // process duplicate edge just once
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 if (!detect_init_independence(m, st_is_pinned, count)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2957
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2960
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 // Here are all the checks a Store must pass before it can be moved into
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 // an initialization. Returns zero if a check fails.
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 // On success, returns the (constant) offset to which the store applies,
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 // within the initialized memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 const int FAIL = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 if (st->req() != MemNode::ValueIn + 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 return FAIL; // an inscrutable StoreNode (card mark?)
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 Node* ctl = st->in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 if (!(ctl != NULL && ctl->is_Proj() && ctl->in(0) == this))
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 return FAIL; // must be unconditional after the initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 Node* mem = st->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 if (!(mem->is_Proj() && mem->in(0) == this))
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 return FAIL; // must not be preceded by other stores
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 Node* adr = st->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 intptr_t offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 AllocateNode* alloc = AllocateNode::Ideal_allocation(adr, phase, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 if (alloc == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 return FAIL; // inscrutable address
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 if (alloc != allocation())
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 return FAIL; // wrong allocation! (store needs to float up)
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 Node* val = st->in(MemNode::ValueIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 int complexity_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 if (!detect_init_independence(val, true, complexity_count))
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 return FAIL; // stored value must be 'simple enough'
a61af66fc99e Initial load
duke
parents:
diff changeset
2986
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 return offset; // success
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2989
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 // Find the captured store in(i) which corresponds to the range
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 // [start..start+size) in the initialized object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 // If there is one, return its index i. If there isn't, return the
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 // negative of the index where it should be inserted.
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 // Return 0 if the queried range overlaps an initialization boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 // or if dead code is encountered.
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 // If size_in_bytes is zero, do not bother with overlap checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 int InitializeNode::captured_store_insertion_point(intptr_t start,
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 int size_in_bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 const int FAIL = 0, MAX_STORE = BytesPerLong;
a61af66fc99e Initial load
duke
parents:
diff changeset
3001
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 if (is_complete())
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 return FAIL; // arraycopy got here first; punt
a61af66fc99e Initial load
duke
parents:
diff changeset
3004
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 assert(allocation() != NULL, "must be present");
a61af66fc99e Initial load
duke
parents:
diff changeset
3006
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 // no negatives, no header fields:
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3008 if (start < (intptr_t) allocation()->minimum_header_size()) return FAIL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3009
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 // after a certain size, we bail out on tracking all the stores:
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 if (start >= ti_limit) return FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3013
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 for (uint i = InitializeNode::RawStores, limit = req(); ; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 if (i >= limit) return -(int)i; // not found; here is where to put it
a61af66fc99e Initial load
duke
parents:
diff changeset
3016
a61af66fc99e Initial load
duke
parents:
diff changeset
3017 Node* st = in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 intptr_t st_off = get_store_offset(st, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 if (st_off < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 if (st != zero_memory()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 return FAIL; // bail out if there is dead garbage
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 } else if (st_off > start) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 // ...we are done, since stores are ordered
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 if (st_off < start + size_in_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 return FAIL; // the next store overlaps
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 return -(int)i; // not found; here is where to put it
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 } else if (st_off < start) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 if (size_in_bytes != 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 start < st_off + MAX_STORE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 start < st_off + st->as_Store()->memory_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 return FAIL; // the previous store overlaps
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 if (size_in_bytes != 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 st->as_Store()->memory_size() != size_in_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 return FAIL; // mismatched store size
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3042
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 ++i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3046
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 // Look for a captured store which initializes at the offset 'start'
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 // with the given size. If there is no such store, and no other
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 // initialization interferes, then return zero_memory (the memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 // projection of the AllocateNode).
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 Node* InitializeNode::find_captured_store(intptr_t start, int size_in_bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 assert(stores_are_sane(phase), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 int i = captured_store_insertion_point(start, size_in_bytes, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 if (i == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 return NULL; // something is dead
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 } else if (i < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 return zero_memory(); // just primordial zero bits here
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 Node* st = in(i); // here is the store at this position
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 assert(get_store_offset(st->as_Store(), phase) == start, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3065
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 // Create, as a raw pointer, an address within my new object at 'offset'.
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 Node* InitializeNode::make_raw_address(intptr_t offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 Node* addr = in(RawAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 if (offset != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 Compile* C = phase->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 addr = phase->transform( new (C, 4) AddPNode(C->top(), addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 phase->MakeConX(offset)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3077
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 // Clone the given store, converting it into a raw store
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 // initializing a field or element of my new object.
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 // Caller is responsible for retiring the original store,
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 // with subsume_node or the like.
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 // From the example above InitializeNode::InitializeNode,
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 // here are the old stores to be captured:
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 // store1 = (StoreC init.Control init.Memory (+ oop 12) 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 // store2 = (StoreC init.Control store1 (+ oop 14) 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 // Here is the changed code; note the extra edges on init:
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 // alloc = (Allocate ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 // rawoop = alloc.RawAddress
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 // rawstore1 = (StoreC alloc.Control alloc.Memory (+ rawoop 12) 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 // rawstore2 = (StoreC alloc.Control alloc.Memory (+ rawoop 14) 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 // init = (Initialize alloc.Control alloc.Memory rawoop
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 // rawstore1 rawstore2)
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 Node* InitializeNode::capture_store(StoreNode* st, intptr_t start,
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 assert(stores_are_sane(phase), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3099
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 if (start < 0) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 assert(can_capture_store(st, phase) == start, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
3102
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 Compile* C = phase->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 int size_in_bytes = st->memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 int i = captured_store_insertion_point(start, size_in_bytes, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 if (i == 0) return NULL; // bail out
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 Node* prev_mem = NULL; // raw memory for the captured store
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 if (i > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 prev_mem = in(i); // there is a pre-existing store under this one
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 set_req(i, C->top()); // temporarily disconnect it
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 // See StoreNode::Ideal 'st->outcnt() == 1' for the reason to disconnect.
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 i = -i; // no pre-existing store
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 prev_mem = zero_memory(); // a slice of the newly allocated object
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 if (i > InitializeNode::RawStores && in(i-1) == prev_mem)
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 set_req(--i, C->top()); // reuse this edge; it has been folded away
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 else
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 ins_req(i, C->top()); // build a new edge
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 Node* new_st = st->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 new_st->set_req(MemNode::Control, in(Control));
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 new_st->set_req(MemNode::Memory, prev_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 new_st->set_req(MemNode::Address, make_raw_address(start, phase));
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 new_st = phase->transform(new_st);
a61af66fc99e Initial load
duke
parents:
diff changeset
3125
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 // At this point, new_st might have swallowed a pre-existing store
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 // at the same offset, or perhaps new_st might have disappeared,
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 // if it redundantly stored the same value (or zero to fresh memory).
a61af66fc99e Initial load
duke
parents:
diff changeset
3129
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 // In any case, wire it in:
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 set_req(i, new_st);
a61af66fc99e Initial load
duke
parents:
diff changeset
3132
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 // The caller may now kill the old guy.
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 DEBUG_ONLY(Node* check_st = find_captured_store(start, size_in_bytes, phase));
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 assert(check_st == new_st || check_st == NULL, "must be findable");
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 assert(!is_complete(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 return new_st;
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3139
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 static bool store_constant(jlong* tiles, int num_tiles,
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 intptr_t st_off, int st_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 jlong con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 if ((st_off & (st_size-1)) != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 return false; // strange store offset (assume size==2**N)
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 address addr = (address)tiles + st_off;
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 assert(st_off >= 0 && addr+st_size <= (address)&tiles[num_tiles], "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 switch (st_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 case sizeof(jbyte): *(jbyte*) addr = (jbyte) con; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 case sizeof(jchar): *(jchar*) addr = (jchar) con; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 case sizeof(jint): *(jint*) addr = (jint) con; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 case sizeof(jlong): *(jlong*) addr = (jlong) con; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 default: return false; // strange store size (detect size!=2**N here)
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 return true; // return success to caller
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3156
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 // Coalesce subword constants into int constants and possibly
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 // into long constants. The goal, if the CPU permits,
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 // is to initialize the object with a small number of 64-bit tiles.
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 // Also, convert floating-point constants to bit patterns.
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 // Non-constants are not relevant to this pass.
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 // In terms of the running example on InitializeNode::InitializeNode
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 // and InitializeNode::capture_store, here is the transformation
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 // of rawstore1 and rawstore2 into rawstore12:
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 // alloc = (Allocate ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 // rawoop = alloc.RawAddress
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 // tile12 = 0x00010002
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 // rawstore12 = (StoreI alloc.Control alloc.Memory (+ rawoop 12) tile12)
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 // init = (Initialize alloc.Control alloc.Memory rawoop rawstore12)
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 InitializeNode::coalesce_subword_stores(intptr_t header_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 Node* size_in_bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 Compile* C = phase->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
3177
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 assert(stores_are_sane(phase), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 // Note: After this pass, they are not completely sane,
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 // since there may be some overlaps.
a61af66fc99e Initial load
duke
parents:
diff changeset
3181
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 int old_subword = 0, old_long = 0, new_int = 0, new_long = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3183
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, ti_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 size_limit = MIN2(size_limit, ti_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 size_limit = align_size_up(size_limit, BytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 int num_tiles = size_limit / BytesPerLong;
a61af66fc99e Initial load
duke
parents:
diff changeset
3189
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 // allocate space for the tile map:
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 const int small_len = DEBUG_ONLY(true ? 3 :) 30; // keep stack frames small
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 jlong tiles_buf[small_len];
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 Node* nodes_buf[small_len];
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 jlong inits_buf[small_len];
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 jlong* tiles = ((num_tiles <= small_len) ? &tiles_buf[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 : NEW_RESOURCE_ARRAY(jlong, num_tiles));
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 Node** nodes = ((num_tiles <= small_len) ? &nodes_buf[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 : NEW_RESOURCE_ARRAY(Node*, num_tiles));
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 jlong* inits = ((num_tiles <= small_len) ? &inits_buf[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 : NEW_RESOURCE_ARRAY(jlong, num_tiles));
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 // tiles: exact bitwise model of all primitive constants
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 // nodes: last constant-storing node subsumed into the tiles model
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 // inits: which bytes (in each tile) are touched by any initializations
a61af66fc99e Initial load
duke
parents:
diff changeset
3204
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 //// Pass A: Fill in the tile model with any relevant stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
3206
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 Copy::zero_to_bytes(tiles, sizeof(tiles[0]) * num_tiles);
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 Copy::zero_to_bytes(nodes, sizeof(nodes[0]) * num_tiles);
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 Copy::zero_to_bytes(inits, sizeof(inits[0]) * num_tiles);
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 Node* zmem = zero_memory(); // initially zero memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 Node* st = in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 intptr_t st_off = get_store_offset(st, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3214
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 // Figure out the store's offset and constant value:
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 if (st_off < header_size) continue; //skip (ignore header)
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 if (st->in(MemNode::Memory) != zmem) continue; //skip (odd store chain)
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 int st_size = st->as_Store()->memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 if (st_off + st_size > size_limit) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3220
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 // Record which bytes are touched, whether by constant or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 if (!store_constant(inits, num_tiles, st_off, st_size, (jlong) -1))
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 continue; // skip (strange store size)
a61af66fc99e Initial load
duke
parents:
diff changeset
3224
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 const Type* val = phase->type(st->in(MemNode::ValueIn));
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 if (!val->singleton()) continue; //skip (non-con store)
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 BasicType type = val->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3228
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 jlong con = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 case T_INT: con = val->is_int()->get_con(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 case T_LONG: con = val->is_long()->get_con(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 case T_FLOAT: con = jint_cast(val->getf()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 case T_DOUBLE: con = jlong_cast(val->getd()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 default: continue; //skip (odd store type)
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3237
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 if (type == T_LONG && Matcher::isSimpleConstant64(con) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 st->Opcode() == Op_StoreL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 continue; // This StoreL is already optimal.
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3242
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 // Store down the constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 store_constant(tiles, num_tiles, st_off, st_size, con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3245
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 intptr_t j = st_off >> LogBytesPerLong;
a61af66fc99e Initial load
duke
parents:
diff changeset
3247
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 if (type == T_INT && st_size == BytesPerInt
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 && (st_off & BytesPerInt) == BytesPerInt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 jlong lcon = tiles[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 if (!Matcher::isSimpleConstant64(lcon) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 st->Opcode() == Op_StoreI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 // This StoreI is already optimal by itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 jint* intcon = (jint*) &tiles[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 intcon[1] = 0; // undo the store_constant()
a61af66fc99e Initial load
duke
parents:
diff changeset
3256
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 // If the previous store is also optimal by itself, back up and
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 // undo the action of the previous loop iteration... if we can.
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 // But if we can't, just let the previous half take care of itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 st = nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 st_off -= BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 con = intcon[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 if (con != 0 && st != NULL && st->Opcode() == Op_StoreI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 assert(st_off >= header_size, "still ignoring header");
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 assert(get_store_offset(st, phase) == st_off, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 assert(in(i-1) == zmem, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 DEBUG_ONLY(const Type* tcon = phase->type(st->in(MemNode::ValueIn)));
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 assert(con == tcon->is_int()->get_con(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 // Undo the effects of the previous loop trip, which swallowed st:
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 intcon[0] = 0; // undo store_constant()
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 set_req(i-1, st); // undo set_req(i, zmem)
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 nodes[j] = NULL; // undo nodes[j] = st
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 --old_subword; // undo ++old_subword
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 continue; // This StoreI is already optimal.
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3278
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 // This store is not needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 set_req(i, zmem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 nodes[j] = st; // record for the moment
a61af66fc99e Initial load
duke
parents:
diff changeset
3282 if (st_size < BytesPerLong) // something has changed
a61af66fc99e Initial load
duke
parents:
diff changeset
3283 ++old_subword; // includes int/float, but who's counting...
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 else ++old_long;
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3286
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 if ((old_subword + old_long) == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 return; // nothing more to do
a61af66fc99e Initial load
duke
parents:
diff changeset
3289
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 //// Pass B: Convert any non-zero tiles into optimal constant stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
3291 // Be sure to insert them before overlapping non-constant stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 // (E.g., byte[] x = { 1,2,y,4 } => x[int 0] = 0x01020004, x[2]=y.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 for (int j = 0; j < num_tiles; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 jlong con = tiles[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 jlong init = inits[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 if (con == 0) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 jint con0, con1; // split the constant, address-wise
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 jint init0, init1; // split the init map, address-wise
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 { union { jlong con; jint intcon[2]; } u;
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 u.con = con;
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 con0 = u.intcon[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 con1 = u.intcon[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
3303 u.con = init;
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 init0 = u.intcon[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
3305 init1 = u.intcon[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
3306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3307
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 Node* old = nodes[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 assert(old != NULL, "need the prior store");
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 intptr_t offset = (j * BytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
3311
a61af66fc99e Initial load
duke
parents:
diff changeset
3312 bool split = !Matcher::isSimpleConstant64(con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3313
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 if (offset < header_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3315 assert(offset + BytesPerInt >= header_size, "second int counts");
a61af66fc99e Initial load
duke
parents:
diff changeset
3316 assert(*(jint*)&tiles[j] == 0, "junk in header");
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 split = true; // only the second word counts
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 // Example: int a[] = { 42 ... }
a61af66fc99e Initial load
duke
parents:
diff changeset
3319 } else if (con0 == 0 && init0 == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 split = true; // first word is covered by full inits
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 // Example: int a[] = { ... foo(), 42 ... }
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 } else if (con1 == 0 && init1 == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3323 split = true; // second word is covered by full inits
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 // Example: int a[] = { ... 42, foo() ... }
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3326
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 // Here's a case where init0 is neither 0 nor -1:
a61af66fc99e Initial load
duke
parents:
diff changeset
3328 // byte a[] = { ... 0,0,foo(),0, 0,0,0,42 ... }
a61af66fc99e Initial load
duke
parents:
diff changeset
3329 // Assuming big-endian memory, init0, init1 are 0x0000FF00, 0x000000FF.
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 // In this case the tile is not split; it is (jlong)42.
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 // The big tile is stored down, and then the foo() value is inserted.
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 // (If there were foo(),foo() instead of foo(),0, init0 would be -1.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3333
a61af66fc99e Initial load
duke
parents:
diff changeset
3334 Node* ctl = old->in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 Node* adr = make_raw_address(offset, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 const TypePtr* atp = TypeRawPtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
3337
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 // One or two coalesced stores to plop down.
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 Node* st[2];
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 intptr_t off[2];
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 int nst = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 if (!split) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 ++new_long;
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 off[nst] = offset;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3345 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 phase->longcon(con), T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 // Omit either if it is a zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 if (con0 != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3350 ++new_int;
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 off[nst] = offset;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3352 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 phase->intcon(con0), T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 if (con1 != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 ++new_int;
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 offset += BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 adr = make_raw_address(offset, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 off[nst] = offset;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3360 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 phase->intcon(con1), T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3364
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 // Insert second store first, then the first before the second.
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 // Insert each one just before any overlapping non-constant stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 while (nst > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 Node* st1 = st[--nst];
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 C->copy_node_notes_to(st1, old);
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 st1 = phase->transform(st1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 offset = off[nst];
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 assert(offset >= header_size, "do not smash header");
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 int ins_idx = captured_store_insertion_point(offset, /*size:*/0, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 guarantee(ins_idx != 0, "must re-insert constant store");
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 if (ins_idx < 0) ins_idx = -ins_idx; // never overlap
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 if (ins_idx > InitializeNode::RawStores && in(ins_idx-1) == zmem)
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 set_req(--ins_idx, st1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 else
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 ins_req(ins_idx, st1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3382
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 if (PrintCompilation && WizardMode)
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 tty->print_cr("Changed %d/%d subword/long constants into %d/%d int/long",
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 old_subword, old_long, new_int, new_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 if (C->log() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 C->log()->elem("comment that='%d/%d subword/long to %d/%d int/long'",
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 old_subword, old_long, new_int, new_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
3389
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 // Clean up any remaining occurrences of zmem:
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 remove_extra_zeroes();
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3393
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 // Explore forward from in(start) to find the first fully initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
3395 // word, and return its offset. Skip groups of subword stores which
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 // together initialize full words. If in(start) is itself part of a
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 // fully initialized word, return the offset of in(start). If there
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 // are no following full-word stores, or if something is fishy, return
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 // a negative value.
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 intptr_t InitializeNode::find_next_fullword_store(uint start, PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 int int_map = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 intptr_t int_map_off = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 const int FULL_MAP = right_n_bits(BytesPerInt); // the int_map we hope for
a61af66fc99e Initial load
duke
parents:
diff changeset
3404
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 for (uint i = start, limit = req(); i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 Node* st = in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3407
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 intptr_t st_off = get_store_offset(st, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 if (st_off < 0) break; // return conservative answer
a61af66fc99e Initial load
duke
parents:
diff changeset
3410
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 int st_size = st->as_Store()->memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 if (st_size >= BytesPerInt && (st_off % BytesPerInt) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 return st_off; // we found a complete word init
a61af66fc99e Initial load
duke
parents:
diff changeset
3414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3415
a61af66fc99e Initial load
duke
parents:
diff changeset
3416 // update the map:
a61af66fc99e Initial load
duke
parents:
diff changeset
3417
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 intptr_t this_int_off = align_size_down(st_off, BytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 if (this_int_off != int_map_off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 // reset the map:
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 int_map = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 int_map_off = this_int_off;
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3424
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 int subword_off = st_off - this_int_off;
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 int_map |= right_n_bits(st_size) << subword_off;
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 if ((int_map & FULL_MAP) == FULL_MAP) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 return this_int_off; // we found a complete word init
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3430
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 // Did this store hit or cross the word boundary?
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 intptr_t next_int_off = align_size_down(st_off + st_size, BytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 if (next_int_off == this_int_off + BytesPerInt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 // We passed the current int, without fully initializing it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 int_map_off = next_int_off;
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 int_map >>= BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 } else if (next_int_off > this_int_off + BytesPerInt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 // We passed the current and next int.
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 return this_int_off + BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3442
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3445
a61af66fc99e Initial load
duke
parents:
diff changeset
3446
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 // Called when the associated AllocateNode is expanded into CFG.
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 // At this point, we may perform additional optimizations.
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 // Linearize the stores by ascending offset, to make memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 // activity as coherent as possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 Node* InitializeNode::complete_stores(Node* rawctl, Node* rawmem, Node* rawptr,
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 intptr_t header_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
3453 Node* size_in_bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 assert(!is_complete(), "not already complete");
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 assert(stores_are_sane(phase), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 assert(allocation() != NULL, "must be present");
a61af66fc99e Initial load
duke
parents:
diff changeset
3458
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 remove_extra_zeroes();
a61af66fc99e Initial load
duke
parents:
diff changeset
3460
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 if (ReduceFieldZeroing || ReduceBulkZeroing)
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 // reduce instruction count for common initialization patterns
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 coalesce_subword_stores(header_size, size_in_bytes, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3464
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 Node* zmem = zero_memory(); // initially zero memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 Node* inits = zmem; // accumulating a linearized chain of inits
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 #ifdef ASSERT
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3468 intptr_t first_offset = allocation()->minimum_header_size();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3469 intptr_t last_init_off = first_offset; // previous init offset
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3470 intptr_t last_init_end = first_offset; // previous init offset+size
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3471 intptr_t last_tile_end = first_offset; // previous tile offset+size
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 intptr_t zeroes_done = header_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3474
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 bool do_zeroing = true; // we might give up if inits are very sparse
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 int big_init_gaps = 0; // how many large gaps have we seen?
a61af66fc99e Initial load
duke
parents:
diff changeset
3477
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 if (ZeroTLAB) do_zeroing = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 if (!ReduceFieldZeroing && !ReduceBulkZeroing) do_zeroing = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3480
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 Node* st = in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 intptr_t st_off = get_store_offset(st, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 if (st_off < 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 break; // unknown junk in the inits
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 if (st->in(MemNode::Memory) != zmem)
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 break; // complicated store chains somehow in list
a61af66fc99e Initial load
duke
parents:
diff changeset
3488
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 int st_size = st->as_Store()->memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 intptr_t next_init_off = st_off + st_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3491
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 if (do_zeroing && zeroes_done < next_init_off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 // See if this store needs a zero before it or under it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 intptr_t zeroes_needed = st_off;
a61af66fc99e Initial load
duke
parents:
diff changeset
3495
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 if (st_size < BytesPerInt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 // Look for subword stores which only partially initialize words.
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 // If we find some, we must lay down some word-level zeroes first,
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 // underneath the subword stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
3500 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 // Examples:
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 // byte[] a = { p,q,r,s } => a[0]=p,a[1]=q,a[2]=r,a[3]=s
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 // byte[] a = { x,y,0,0 } => a[0..3] = 0, a[0]=x,a[1]=y
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 // byte[] a = { 0,0,z,0 } => a[0..3] = 0, a[2]=z
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 // Note: coalesce_subword_stores may have already done this,
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 // if it was prompted by constant non-zero subword initializers.
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 // But this case can still arise with non-constant stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
3509
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 intptr_t next_full_store = find_next_fullword_store(i, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3511
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 // In the examples above:
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 // in(i) p q r s x y z
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 // st_off 12 13 14 15 12 13 14
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 // st_size 1 1 1 1 1 1 1
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 // next_full_s. 12 16 16 16 16 16 16
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 // z's_done 12 16 16 16 12 16 12
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 // z's_needed 12 16 16 16 16 16 16
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 // zsize 0 0 0 0 4 0 4
a61af66fc99e Initial load
duke
parents:
diff changeset
3520 if (next_full_store < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 // Conservative tack: Zero to end of current word.
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 zeroes_needed = align_size_up(zeroes_needed, BytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 // Zero to beginning of next fully initialized word.
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 // Or, don't zero at all, if we are already in that word.
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 assert(next_full_store >= zeroes_needed, "must go forward");
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 assert((next_full_store & (BytesPerInt-1)) == 0, "even boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 zeroes_needed = next_full_store;
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3531
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 if (zeroes_needed > zeroes_done) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 intptr_t zsize = zeroes_needed - zeroes_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 // Do some incremental zeroing on rawmem, in parallel with inits.
a61af66fc99e Initial load
duke
parents:
diff changeset
3535 zeroes_done = align_size_down(zeroes_done, BytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr,
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 zeroes_done, zeroes_needed,
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 zeroes_done = zeroes_needed;
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 if (zsize > Matcher::init_array_short_size && ++big_init_gaps > 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 do_zeroing = false; // leave the hole, next time
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3544
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 // Collect the store and move on:
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 st->set_req(MemNode::Memory, inits);
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 inits = st; // put it on the linearized chain
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 set_req(i, zmem); // unhook from previous position
a61af66fc99e Initial load
duke
parents:
diff changeset
3549
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 if (zeroes_done == st_off)
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 zeroes_done = next_init_off;
a61af66fc99e Initial load
duke
parents:
diff changeset
3552
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 assert(!do_zeroing || zeroes_done >= next_init_off, "don't miss any");
a61af66fc99e Initial load
duke
parents:
diff changeset
3554
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 // Various order invariants. Weaker than stores_are_sane because
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 // a large constant tile can be filled in by smaller non-constant stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 assert(st_off >= last_init_off, "inits do not reverse");
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 last_init_off = st_off;
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 const Type* val = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3561 if (st_size >= BytesPerInt &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 (val = phase->type(st->in(MemNode::ValueIn)))->singleton() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 (int)val->basic_type() < (int)T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 assert(st_off >= last_tile_end, "tiles do not overlap");
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 assert(st_off >= last_init_end, "tiles do not overwrite inits");
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 last_tile_end = MAX2(last_tile_end, next_init_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 intptr_t st_tile_end = align_size_up(next_init_off, BytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 assert(st_tile_end >= last_tile_end, "inits stay with tiles");
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 assert(st_off >= last_init_end, "inits do not overlap");
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 last_init_end = next_init_off; // it's a non-tile
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3575
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 remove_extra_zeroes(); // clear out all the zmems left over
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 add_req(inits);
a61af66fc99e Initial load
duke
parents:
diff changeset
3578
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 if (!ZeroTLAB) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 // If anything remains to be zeroed, zero it all now.
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 zeroes_done = align_size_down(zeroes_done, BytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 // if it is the last unused 4 bytes of an instance, forget about it
a61af66fc99e Initial load
duke
parents:
diff changeset
3583 intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, max_jint);
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 if (zeroes_done + BytesPerLong >= size_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 assert(allocation() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 Node* klass_node = allocation()->in(AllocateNode::KlassNode);
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 ciKlass* k = phase->type(klass_node)->is_klassptr()->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 if (zeroes_done == k->layout_helper())
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 zeroes_done = size_limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 if (zeroes_done < size_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr,
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 zeroes_done, size_in_bytes, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3596
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 set_complete(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 return rawmem;
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3600
a61af66fc99e Initial load
duke
parents:
diff changeset
3601
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 bool InitializeNode::stores_are_sane(PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 if (is_complete())
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 return true; // stores could be anything at this point
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3606 assert(allocation() != NULL, "must be present");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 82
diff changeset
3607 intptr_t last_off = allocation()->minimum_header_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 for (uint i = InitializeNode::RawStores; i < req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 Node* st = in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 intptr_t st_off = get_store_offset(st, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 if (st_off < 0) continue; // ignore dead garbage
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 if (last_off > st_off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 tty->print_cr("*** bad store offset at %d: %d > %d", i, last_off, st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 this->dump(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 assert(false, "ascending store offsets");
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 last_off = st_off + st->as_Store()->memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3623
a61af66fc99e Initial load
duke
parents:
diff changeset
3624
a61af66fc99e Initial load
duke
parents:
diff changeset
3625
a61af66fc99e Initial load
duke
parents:
diff changeset
3626
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 //============================MergeMemNode=====================================
a61af66fc99e Initial load
duke
parents:
diff changeset
3628 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 // SEMANTICS OF MEMORY MERGES: A MergeMem is a memory state assembled from several
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 // contributing store or call operations. Each contributor provides the memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 // state for a particular "alias type" (see Compile::alias_type). For example,
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 // if a MergeMem has an input X for alias category #6, then any memory reference
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 // to alias category #6 may use X as its memory state input, as an exact equivalent
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 // to using the MergeMem as a whole.
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 // Load<6>( MergeMem(<6>: X, ...), p ) <==> Load<6>(X,p)
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 // (Here, the <N> notation gives the index of the relevant adr_type.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 // In one special case (and more cases in the future), alias categories overlap.
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 // The special alias category "Bot" (Compile::AliasIdxBot) includes all memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 // states. Therefore, if a MergeMem has only one contributing input W for Bot,
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 // it is exactly equivalent to that state W:
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 // MergeMem(<Bot>: W) <==> W
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 // Usually, the merge has more than one input. In that case, where inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 // overlap (i.e., one is Bot), the narrower alias type determines the memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 // state for that type, and the wider alias type (Bot) fills in everywhere else:
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 // Load<5>( MergeMem(<Bot>: W, <6>: X), p ) <==> Load<5>(W,p)
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 // Load<6>( MergeMem(<Bot>: W, <6>: X), p ) <==> Load<6>(X,p)
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 // A merge can take a "wide" memory state as one of its narrow inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 // This simply means that the merge observes out only the relevant parts of
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 // the wide input. That is, wide memory states arriving at narrow merge inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 // are implicitly "filtered" or "sliced" as necessary. (This is rare.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 // These rules imply that MergeMem nodes may cascade (via their <Bot> links),
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 // and that memory slices "leak through":
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 // MergeMem(<Bot>: MergeMem(<Bot>: W, <7>: Y)) <==> MergeMem(<Bot>: W, <7>: Y)
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 // But, in such a cascade, repeated memory slices can "block the leak":
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 // MergeMem(<Bot>: MergeMem(<Bot>: W, <7>: Y), <7>: Y') <==> MergeMem(<Bot>: W, <7>: Y')
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 // In the last example, Y is not part of the combined memory state of the
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 // outermost MergeMem. The system must, of course, prevent unschedulable
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 // memory states from arising, so you can be sure that the state Y is somehow
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 // a precursor to state Y'.
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // REPRESENTATION OF MEMORY MERGES: The indexes used to address the Node::in array
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 // of each MergeMemNode array are exactly the numerical alias indexes, including
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 // but not limited to AliasIdxTop, AliasIdxBot, and AliasIdxRaw. The functions
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 // Compile::alias_type (and kin) produce and manage these indexes.
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 // By convention, the value of in(AliasIdxTop) (i.e., in(1)) is always the top node.
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 // (Note that this provides quick access to the top node inside MergeMem methods,
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 // without the need to reach out via TLS to Compile::current.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 // As a consequence of what was just described, a MergeMem that represents a full
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 // memory state has an edge in(AliasIdxBot) which is a "wide" memory state,
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 // containing all alias categories.
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 // MergeMem nodes never (?) have control inputs, so in(0) is NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // All other edges in(N) (including in(AliasIdxRaw), which is in(3)) are either
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 // a memory state for the alias type <N>, or else the top node, meaning that
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 // there is no particular input for that alias type. Note that the length of
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 // a MergeMem is variable, and may be extended at any time to accommodate new
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 // memory states at larger alias indexes. When merges grow, they are of course
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 // filled with "top" in the unused in() positions.
a61af66fc99e Initial load
duke
parents:
diff changeset
3690 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 // This use of top is named "empty_memory()", or "empty_mem" (no-memory) as a variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 // (Top was chosen because it works smoothly with passes like GCM.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 // For convenience, we hardwire the alias index for TypeRawPtr::BOTTOM. (It is
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 // the type of random VM bits like TLS references.) Since it is always the
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 // first non-Bot memory slice, some low-level loops use it to initialize an
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 // index variable: for (i = AliasIdxRaw; i < req(); i++).
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 // ACCESSORS: There is a special accessor MergeMemNode::base_memory which returns
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 // the distinguished "wide" state. The accessor MergeMemNode::memory_at(N) returns
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 // the memory state for alias type <N>, or (if there is no particular slice at <N>,
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 // it returns the base memory. To prevent bugs, memory_at does not accept <Top>
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 // or <Bot> indexes. The iterator MergeMemStream provides robust iteration over
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 // MergeMem nodes or pairs of such nodes, ensuring that the non-top edges are visited.
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 // %%%% We may get rid of base_memory as a separate accessor at some point; it isn't
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 // really that different from the other memory inputs. An abbreviation called
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 // "bot_memory()" for "memory_at(AliasIdxBot)" would keep code tidy.
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 // PARTIAL MEMORY STATES: During optimization, MergeMem nodes may arise that represent
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 // partial memory states. When a Phi splits through a MergeMem, the copy of the Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 // that "emerges though" the base memory will be marked as excluding the alias types
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 // of the other (narrow-memory) copies which "emerged through" the narrow edges:
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 // Phi<Bot>(U, MergeMem(<Bot>: W, <8>: Y))
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 // ==Ideal=> MergeMem(<Bot>: Phi<Bot-8>(U, W), Phi<8>(U, Y))
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 // This strange "subtraction" effect is necessary to ensure IGVN convergence.
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 // (It is currently unimplemented.) As you can see, the resulting merge is
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 // actually a disjoint union of memory states, rather than an overlay.
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3724
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 //------------------------------MergeMemNode-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 Node* MergeMemNode::make_empty_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 Node* empty_memory = (Node*) Compile::current()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 assert(empty_memory->is_top(), "correct sentinel identity");
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 return empty_memory;
a61af66fc99e Initial load
duke
parents:
diff changeset
3730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3731
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 MergeMemNode::MergeMemNode(Node *new_base) : Node(1+Compile::AliasIdxRaw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 init_class_id(Class_MergeMem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 // all inputs are nullified in Node::Node(int)
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 // set_input(0, NULL); // no control input
a61af66fc99e Initial load
duke
parents:
diff changeset
3736
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 // Initialize the edges uniformly to top, for starters.
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 Node* empty_mem = make_empty_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 for (uint i = Compile::AliasIdxTop; i < req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 init_req(i,empty_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 assert(empty_memory() == empty_mem, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 if( new_base != NULL && new_base->is_MergeMem() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 MergeMemNode* mdef = new_base->as_MergeMem();
a61af66fc99e Initial load
duke
parents:
diff changeset
3746 assert(mdef->empty_memory() == empty_mem, "consistent sentinels");
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 for (MergeMemStream mms(this, mdef); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3748 mms.set_memory(mms.memory2());
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 assert(base_memory() == mdef->base_memory(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 set_base_memory(new_base);
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3755
a61af66fc99e Initial load
duke
parents:
diff changeset
3756 // Make a new, untransformed MergeMem with the same base as 'mem'.
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 // If mem is itself a MergeMem, populate the result with the same edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 MergeMemNode* MergeMemNode::make(Compile* C, Node* mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 return new(C, 1+Compile::AliasIdxRaw) MergeMemNode(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3761
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 //------------------------------cmp--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 uint MergeMemNode::hash() const { return NO_HASH; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 uint MergeMemNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 return (&n == this); // Always fail except on self
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3767
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 Node* MergeMemNode::Identity(PhaseTransform *phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 // Identity if this merge point does not record any interesting memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 // disambiguations.
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 Node* base_mem = base_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 Node* empty_mem = empty_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 if (base_mem != empty_mem) { // Memory path is not dead?
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 for (uint i = Compile::AliasIdxRaw; i < req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 Node* mem = in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 if (mem != empty_mem && mem != base_mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 return this; // Many memory splits; no change
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3782 return base_mem; // No memory splits; ID on the one true input
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3784
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 // This method is invoked recursively on chains of MergeMem nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 Node *MergeMemNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 // Remove chain'd MergeMems
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 // This is delicate, because the each "in(i)" (i >= Raw) is interpreted
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 // relative to the "in(Bot)". Since we are patching both at the same time,
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 // we have to be careful to read each "in(i)" relative to the old "in(Bot)",
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 // but rewrite each "in(i)" relative to the new "in(Bot)".
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 Node *progress = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3795
a61af66fc99e Initial load
duke
parents:
diff changeset
3796
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 Node* old_base = base_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 Node* empty_mem = empty_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 if (old_base == empty_mem)
a61af66fc99e Initial load
duke
parents:
diff changeset
3800 return NULL; // Dead memory path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3801
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 MergeMemNode* old_mbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 if (old_base != NULL && old_base->is_MergeMem())
a61af66fc99e Initial load
duke
parents:
diff changeset
3804 old_mbase = old_base->as_MergeMem();
a61af66fc99e Initial load
duke
parents:
diff changeset
3805 else
a61af66fc99e Initial load
duke
parents:
diff changeset
3806 old_mbase = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 Node* new_base = old_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
3808
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 // simplify stacked MergeMems in base memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 if (old_mbase) new_base = old_mbase->base_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3811
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 // the base memory might contribute new slices beyond my req()
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 if (old_mbase) grow_to_match(old_mbase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3814
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 // Look carefully at the base node if it is a phi.
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 PhiNode* phi_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 if (new_base != NULL && new_base->is_Phi())
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 phi_base = new_base->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 else
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 phi_base = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3821
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 Node* phi_reg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 uint phi_len = (uint)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 if (phi_base != NULL && !phi_base->is_copy()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 // do not examine phi if degraded to a copy
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 phi_reg = phi_base->region();
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 phi_len = phi_base->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
3828 // see if the phi is unfinished
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 for (uint i = 1; i < phi_len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 if (phi_base->in(i) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3831 // incomplete phi; do not look at it yet!
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 phi_reg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 phi_len = (uint)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3834 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3835 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3838
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 // Note: We do not call verify_sparse on entry, because inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
3840 // can normalize to the base_memory via subsume_node or similar
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 // mechanisms. This method repairs that damage.
a61af66fc99e Initial load
duke
parents:
diff changeset
3842
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 assert(!old_mbase || old_mbase->is_empty_memory(empty_mem), "consistent sentinels");
a61af66fc99e Initial load
duke
parents:
diff changeset
3844
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 // Look at each slice.
a61af66fc99e Initial load
duke
parents:
diff changeset
3846 for (uint i = Compile::AliasIdxRaw; i < req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3847 Node* old_in = in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3848 // calculate the old memory value
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 Node* old_mem = old_in;
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 if (old_mem == empty_mem) old_mem = old_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 assert(old_mem == memory_at(i), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3852
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 // maybe update (reslice) the old memory value
a61af66fc99e Initial load
duke
parents:
diff changeset
3854
a61af66fc99e Initial load
duke
parents:
diff changeset
3855 // simplify stacked MergeMems
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 Node* new_mem = old_mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 MergeMemNode* old_mmem;
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 if (old_mem != NULL && old_mem->is_MergeMem())
a61af66fc99e Initial load
duke
parents:
diff changeset
3859 old_mmem = old_mem->as_MergeMem();
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 else
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 old_mmem = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3862 if (old_mmem == this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 // This can happen if loops break up and safepoints disappear.
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 // A merge of BotPtr (default) with a RawPtr memory derived from a
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 // safepoint can be rewritten to a merge of the same BotPtr with
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 // the BotPtr phi coming into the loop. If that phi disappears
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 // also, we can end up with a self-loop of the mergemem.
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 // In general, if loops degenerate and memory effects disappear,
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 // a mergemem can be left looking at itself. This simply means
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 // that the mergemem's default should be used, since there is
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 // no longer any apparent effect on this slice.
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 // Note: If a memory slice is a MergeMem cycle, it is unreachable
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 // from start. Update the input to TOP.
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 new_mem = (new_base == this || new_base == empty_mem)? empty_mem : new_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
3875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 else if (old_mmem != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 new_mem = old_mmem->memory_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 }
605
98cb887364d3 6810672: Comment typos
twisti
parents: 583
diff changeset
3879 // else preceding memory was not a MergeMem
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3880
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 // replace equivalent phis (unfortunately, they do not GVN together)
a61af66fc99e Initial load
duke
parents:
diff changeset
3882 if (new_mem != NULL && new_mem != new_base &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 new_mem->req() == phi_len && new_mem->in(0) == phi_reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 if (new_mem->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3885 PhiNode* phi_mem = new_mem->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
3886 for (uint i = 1; i < phi_len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3887 if (phi_base->in(i) != phi_mem->in(i)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3888 phi_mem = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3892 if (phi_mem != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 // equivalent phi nodes; revert to the def
a61af66fc99e Initial load
duke
parents:
diff changeset
3894 new_mem = new_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
3895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3898
a61af66fc99e Initial load
duke
parents:
diff changeset
3899 // maybe store down a new value
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 Node* new_in = new_mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 if (new_in == new_base) new_in = empty_mem;
a61af66fc99e Initial load
duke
parents:
diff changeset
3902
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 if (new_in != old_in) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 // Warning: Do not combine this "if" with the previous "if"
a61af66fc99e Initial load
duke
parents:
diff changeset
3905 // A memory slice might have be be rewritten even if it is semantically
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 // unchanged, if the base_memory value has changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 set_req(i, new_in);
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 progress = this; // Report progress
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3911
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 if (new_base != old_base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3913 set_req(Compile::AliasIdxBot, new_base);
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 // Don't use set_base_memory(new_base), because we need to update du.
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 assert(base_memory() == new_base, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 progress = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
3917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3918
a61af66fc99e Initial load
duke
parents:
diff changeset
3919 if( base_memory() == this ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3920 // a self cycle indicates this memory path is dead
a61af66fc99e Initial load
duke
parents:
diff changeset
3921 set_req(Compile::AliasIdxBot, empty_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3923
a61af66fc99e Initial load
duke
parents:
diff changeset
3924 // Resolve external cycles by calling Ideal on a MergeMem base_memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3925 // Recursion must occur after the self cycle check above
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 if( base_memory()->is_MergeMem() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 MergeMemNode *new_mbase = base_memory()->as_MergeMem();
a61af66fc99e Initial load
duke
parents:
diff changeset
3928 Node *m = phase->transform(new_mbase); // Rollup any cycles
a61af66fc99e Initial load
duke
parents:
diff changeset
3929 if( m != NULL && (m->is_top() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 m->is_MergeMem() && m->as_MergeMem()->base_memory() == empty_mem) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 // propagate rollup of dead cycle to self
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 set_req(Compile::AliasIdxBot, empty_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3935
a61af66fc99e Initial load
duke
parents:
diff changeset
3936 if( base_memory() == empty_mem ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 progress = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
3938 // Cut inputs during Parse phase only.
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 // During Optimize phase a dead MergeMem node will be subsumed by Top.
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 if( !can_reshape ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3941 for (uint i = Compile::AliasIdxRaw; i < req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 if( in(i) != empty_mem ) { set_req(i, empty_mem); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3946
a61af66fc99e Initial load
duke
parents:
diff changeset
3947 if( !progress && base_memory()->is_Phi() && can_reshape ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 // Check if PhiNode::Ideal's "Split phis through memory merges"
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 // transform should be attempted. Look for this->phi->this cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 uint merge_width = req();
a61af66fc99e Initial load
duke
parents:
diff changeset
3951 if (merge_width > Compile::AliasIdxRaw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 PhiNode* phi = base_memory()->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 for( uint i = 1; i < phi->req(); ++i ) {// For all paths in
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 if (phi->in(i) == this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 phase->is_IterGVN()->_worklist.push(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3961
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 43
diff changeset
3962 assert(progress || verify_sparse(), "please, no dups of base");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 return progress;
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3965
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 //-------------------------set_base_memory-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 void MergeMemNode::set_base_memory(Node *new_base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 Node* empty_mem = empty_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 set_req(Compile::AliasIdxBot, new_base);
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 assert(memory_at(req()) == new_base, "must set default memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 // Clear out other occurrences of new_base:
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 if (new_base != empty_mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 for (uint i = Compile::AliasIdxRaw; i < req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 if (in(i) == new_base) set_req(i, empty_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3978
a61af66fc99e Initial load
duke
parents:
diff changeset
3979 //------------------------------out_RegMask------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 const RegMask &MergeMemNode::out_RegMask() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3983
a61af66fc99e Initial load
duke
parents:
diff changeset
3984 //------------------------------dump_spec--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 void MergeMemNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3987 st->print(" {");
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 Node* base_mem = base_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3989 for( uint i = Compile::AliasIdxRaw; i < req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 Node* mem = memory_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3991 if (mem == base_mem) { st->print(" -"); continue; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 st->print( " N%d:", mem->_idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3993 Compile::current()->get_adr_type(i)->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3995 st->print(" }");
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 #endif // !PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3998
a61af66fc99e Initial load
duke
parents:
diff changeset
3999
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 static bool might_be_same(Node* a, Node* b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 if (a == b) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 if (!(a->is_Phi() || b->is_Phi())) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4004 // phis shift around during optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 return true; // pretty stupid...
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4007
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 // verify a narrow slice (either incoming or outgoing)
a61af66fc99e Initial load
duke
parents:
diff changeset
4009 static void verify_memory_slice(const MergeMemNode* m, int alias_idx, Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 if (!VerifyAliases) return; // don't bother to verify unless requested
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 if (is_error_reported()) return; // muzzle asserts when debugging an error
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 if (Node::in_dump()) return; // muzzle asserts when printing
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 assert(alias_idx >= Compile::AliasIdxRaw, "must not disturb base_memory or sentinel");
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 assert(n != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
4015 // Elide intervening MergeMem's
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 while (n->is_MergeMem()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 n = n->as_MergeMem()->memory_at(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4019 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 const TypePtr* n_adr_type = n->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 if (n == m->empty_memory()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 // Implicit copy of base_memory()
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 } else if (n_adr_type != TypePtr::BOTTOM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4024 assert(n_adr_type != NULL, "new memory must have a well-defined adr_type");
a61af66fc99e Initial load
duke
parents:
diff changeset
4025 assert(C->must_alias(n_adr_type, alias_idx), "new memory must match selected slice");
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 // A few places like make_runtime_call "know" that VM calls are narrow,
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 // and can be used to update only the VM bits stored as TypeRawPtr::BOTTOM.
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 bool expected_wide_mem = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 if (n == m->base_memory()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 expected_wide_mem = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 } else if (alias_idx == Compile::AliasIdxRaw ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 n == m->memory_at(Compile::AliasIdxRaw)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 expected_wide_mem = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 } else if (!C->alias_type(alias_idx)->is_rewritable()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 // memory can "leak through" calls on channels that
a61af66fc99e Initial load
duke
parents:
diff changeset
4037 // are write-once. Allow this also.
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 expected_wide_mem = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 assert(expected_wide_mem, "expected narrow slice replacement");
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 #else // !ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 #define verify_memory_slice(m,i,n) (0) // PRODUCT version is no-op
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4046
a61af66fc99e Initial load
duke
parents:
diff changeset
4047
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 //-----------------------------memory_at---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4049 Node* MergeMemNode::memory_at(uint alias_idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 assert(alias_idx >= Compile::AliasIdxRaw ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4051 alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 "must avoid base_memory and AliasIdxTop");
a61af66fc99e Initial load
duke
parents:
diff changeset
4053
a61af66fc99e Initial load
duke
parents:
diff changeset
4054 // Otherwise, it is a narrow slice.
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 Node* n = alias_idx < req() ? in(alias_idx) : empty_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
4056 Compile *C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
4057 if (is_empty_memory(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4058 // the array is sparse; empty slots are the "top" node
a61af66fc99e Initial load
duke
parents:
diff changeset
4059 n = base_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 assert(Node::in_dump()
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 || n == NULL || n->bottom_type() == Type::TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
4062 || n->adr_type() == TypePtr::BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
4063 || n->adr_type() == TypeRawPtr::BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 || Compile::current()->AliasLevel() == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
4065 "must be a wide memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
4066 // AliasLevel == 0 if we are organizing the memory states manually.
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 // See verify_memory_slice for comments on TypeRawPtr::BOTTOM.
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4069 // make sure the stored slice is sane
a61af66fc99e Initial load
duke
parents:
diff changeset
4070 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
4071 if (is_error_reported() || Node::in_dump()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 } else if (might_be_same(n, base_memory())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 // Give it a pass: It is a mostly harmless repetition of the base.
a61af66fc99e Initial load
duke
parents:
diff changeset
4074 // This can arise normally from node subsumption during optimization.
a61af66fc99e Initial load
duke
parents:
diff changeset
4075 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 verify_memory_slice(this, alias_idx, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
4077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4078 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4080 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
4081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4082
a61af66fc99e Initial load
duke
parents:
diff changeset
4083 //---------------------------set_memory_at-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4084 void MergeMemNode::set_memory_at(uint alias_idx, Node *n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 verify_memory_slice(this, alias_idx, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
4086 Node* empty_mem = empty_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 if (n == base_memory()) n = empty_mem; // collapse default
a61af66fc99e Initial load
duke
parents:
diff changeset
4088 uint need_req = alias_idx+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4089 if (req() < need_req) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 if (n == empty_mem) return; // already the default, so do not grow me
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 // grow the sparse array
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 add_req(empty_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 } while (req() < need_req);
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 set_req( alias_idx, n );
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4098
a61af66fc99e Initial load
duke
parents:
diff changeset
4099
a61af66fc99e Initial load
duke
parents:
diff changeset
4100
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 //--------------------------iteration_setup------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 void MergeMemNode::iteration_setup(const MergeMemNode* other) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4103 if (other != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4104 grow_to_match(other);
a61af66fc99e Initial load
duke
parents:
diff changeset
4105 // invariant: the finite support of mm2 is within mm->req()
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 for (uint i = req(); i < other->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4108 assert(other->is_empty_memory(other->in(i)), "slice left uncovered");
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 // Replace spurious copies of base_memory by top.
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 Node* base_mem = base_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 if (base_mem != NULL && !base_mem->is_top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4115 for (uint i = Compile::AliasIdxBot+1, imax = req(); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 if (in(i) == base_mem)
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 set_req(i, empty_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
4118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4121
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 //---------------------------grow_to_match-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4123 void MergeMemNode::grow_to_match(const MergeMemNode* other) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4124 Node* empty_mem = empty_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
4125 assert(other->is_empty_memory(empty_mem), "consistent sentinels");
a61af66fc99e Initial load
duke
parents:
diff changeset
4126 // look for the finite support of the other memory
a61af66fc99e Initial load
duke
parents:
diff changeset
4127 for (uint i = other->req(); --i >= req(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4128 if (other->in(i) != empty_mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4129 uint new_len = i+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4130 while (req() < new_len) add_req(empty_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4131 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4135
a61af66fc99e Initial load
duke
parents:
diff changeset
4136 //---------------------------verify_sparse-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4137 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
4138 bool MergeMemNode::verify_sparse() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
4139 assert(is_empty_memory(make_empty_memory()), "sane sentinel");
a61af66fc99e Initial load
duke
parents:
diff changeset
4140 Node* base_mem = base_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
4141 // The following can happen in degenerate cases, since empty==top.
a61af66fc99e Initial load
duke
parents:
diff changeset
4142 if (is_empty_memory(base_mem)) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4143 for (uint i = Compile::AliasIdxRaw; i < req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4144 assert(in(i) != NULL, "sane slice");
a61af66fc99e Initial load
duke
parents:
diff changeset
4145 if (in(i) == base_mem) return false; // should have been the sentinel value!
a61af66fc99e Initial load
duke
parents:
diff changeset
4146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4147 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4149
a61af66fc99e Initial load
duke
parents:
diff changeset
4150 bool MergeMemStream::match_memory(Node* mem, const MergeMemNode* mm, int idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4151 Node* n;
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 n = mm->in(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 if (mem == n) return true; // might be empty_memory()
a61af66fc99e Initial load
duke
parents:
diff changeset
4154 n = (idx == Compile::AliasIdxBot)? mm->base_memory(): mm->memory_at(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
4155 if (mem == n) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 while (n->is_Phi() && (n = n->as_Phi()->is_copy()) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4157 if (mem == n) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4158 if (n == NULL) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4160 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 #endif // !PRODUCT