Mercurial > hg > truffle
annotate src/share/vm/ci/bcEscapeAnalyzer.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | da91efe96a93 |
children | bb33c6fdcf0d |
rev | line source |
---|---|
0 | 1 /* |
4869
5ed8f599a788
7140924: SIGSEGV in compiled code for sun.awt.X11.XDecoratedPeer.updateMinSizeHints
kvn
parents:
4122
diff
changeset
|
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
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:
1397
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "ci/bcEscapeAnalyzer.hpp" | |
27 #include "ci/ciConstant.hpp" | |
28 #include "ci/ciField.hpp" | |
29 #include "ci/ciMethodBlocks.hpp" | |
30 #include "ci/ciStreams.hpp" | |
31 #include "interpreter/bytecode.hpp" | |
32 #include "utilities/bitMap.inline.hpp" | |
0 | 33 |
34 | |
35 | |
36 #ifndef PRODUCT | |
37 #define TRACE_BCEA(level, code) \ | |
38 if (EstimateArgEscape && BCEATraceLevel >= level) { \ | |
39 code; \ | |
40 } | |
41 #else | |
42 #define TRACE_BCEA(level, code) | |
43 #endif | |
44 | |
45 // Maintain a map of which aguments a local variable or | |
46 // stack slot may contain. In addition to tracking | |
47 // arguments, it tracks two special values, "allocated" | |
48 // which represents any object allocated in the current | |
49 // method, and "unknown" which is any other object. | |
50 // Up to 30 arguments are handled, with the last one | |
51 // representing summary information for any extra arguments | |
52 class BCEscapeAnalyzer::ArgumentMap { | |
53 uint _bits; | |
54 enum {MAXBIT = 29, | |
55 ALLOCATED = 1, | |
56 UNKNOWN = 2}; | |
57 | |
58 uint int_to_bit(uint e) const { | |
59 if (e > MAXBIT) | |
60 e = MAXBIT; | |
61 return (1 << (e + 2)); | |
62 } | |
63 | |
64 public: | |
65 ArgumentMap() { _bits = 0;} | |
66 void set_bits(uint bits) { _bits = bits;} | |
67 uint get_bits() const { return _bits;} | |
68 void clear() { _bits = 0;} | |
69 void set_all() { _bits = ~0u; } | |
70 bool is_empty() const { return _bits == 0; } | |
71 bool contains(uint var) const { return (_bits & int_to_bit(var)) != 0; } | |
72 bool is_singleton(uint var) const { return (_bits == int_to_bit(var)); } | |
73 bool contains_unknown() const { return (_bits & UNKNOWN) != 0; } | |
74 bool contains_allocated() const { return (_bits & ALLOCATED) != 0; } | |
75 bool contains_vars() const { return (_bits & (((1 << MAXBIT) -1) << 2)) != 0; } | |
76 void set(uint var) { _bits = int_to_bit(var); } | |
77 void add(uint var) { _bits |= int_to_bit(var); } | |
78 void add_unknown() { _bits = UNKNOWN; } | |
79 void add_allocated() { _bits = ALLOCATED; } | |
80 void set_union(const ArgumentMap &am) { _bits |= am._bits; } | |
81 void set_intersect(const ArgumentMap &am) { _bits |= am._bits; } | |
82 void set_difference(const ArgumentMap &am) { _bits &= ~am._bits; } | |
83 void operator=(const ArgumentMap &am) { _bits = am._bits; } | |
84 bool operator==(const ArgumentMap &am) { return _bits == am._bits; } | |
85 bool operator!=(const ArgumentMap &am) { return _bits != am._bits; } | |
86 }; | |
87 | |
88 class BCEscapeAnalyzer::StateInfo { | |
89 public: | |
90 ArgumentMap *_vars; | |
91 ArgumentMap *_stack; | |
92 short _stack_height; | |
93 short _max_stack; | |
94 bool _initialized; | |
95 ArgumentMap empty_map; | |
96 | |
97 StateInfo() { | |
98 empty_map.clear(); | |
99 } | |
100 | |
1747
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
101 ArgumentMap raw_pop() { guarantee(_stack_height > 0, "stack underflow"); return _stack[--_stack_height]; } |
0 | 102 ArgumentMap apop() { return raw_pop(); } |
103 void spop() { raw_pop(); } | |
104 void lpop() { spop(); spop(); } | |
1747
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
105 void raw_push(ArgumentMap i) { guarantee(_stack_height < _max_stack, "stack overflow"); _stack[_stack_height++] = i; } |
0 | 106 void apush(ArgumentMap i) { raw_push(i); } |
107 void spush() { raw_push(empty_map); } | |
108 void lpush() { spush(); spush(); } | |
109 | |
110 }; | |
111 | |
112 void BCEscapeAnalyzer::set_returned(ArgumentMap vars) { | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
113 for (int i = 0; i < _arg_size; i++) { |
0 | 114 if (vars.contains(i)) |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
115 _arg_returned.set(i); |
0 | 116 } |
117 _return_local = _return_local && !(vars.contains_unknown() || vars.contains_allocated()); | |
118 _return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars()); | |
119 } | |
120 | |
121 // return true if any element of vars is an argument | |
122 bool BCEscapeAnalyzer::is_argument(ArgumentMap vars) { | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
123 for (int i = 0; i < _arg_size; i++) { |
0 | 124 if (vars.contains(i)) |
125 return true; | |
126 } | |
127 return false; | |
128 } | |
129 | |
130 // return true if any element of vars is an arg_stack argument | |
131 bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){ | |
132 if (_conservative) | |
133 return true; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
134 for (int i = 0; i < _arg_size; i++) { |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
135 if (vars.contains(i) && _arg_stack.test(i)) |
0 | 136 return true; |
137 } | |
138 return false; | |
139 } | |
140 | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
141 void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) { |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
142 for (int i = 0; i < _arg_size; i++) { |
0 | 143 if (vars.contains(i)) { |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
144 bm >>= i; |
0 | 145 } |
146 } | |
147 } | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
148 |
0 | 149 void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { |
150 clear_bits(vars, _arg_local); | |
151 } | |
152 | |
4122
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
153 void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) { |
0 | 154 clear_bits(vars, _arg_local); |
155 clear_bits(vars, _arg_stack); | |
156 if (vars.contains_allocated()) | |
157 _allocated_escapes = true; | |
4122
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
158 |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
159 if (merge && !vars.is_empty()) { |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
160 // Merge new state into already processed block. |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
161 // New state is not taken into account and |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
162 // it may invalidate set_returned() result. |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
163 if (vars.contains_unknown() || vars.contains_allocated()) { |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
164 _return_local = false; |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
165 } |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
166 if (vars.contains_unknown() || vars.contains_vars()) { |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
167 _return_allocated = false; |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
168 } |
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
169 } |
0 | 170 } |
171 | |
172 void BCEscapeAnalyzer::set_dirty(ArgumentMap vars) { | |
173 clear_bits(vars, _dirty); | |
174 } | |
175 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
176 void BCEscapeAnalyzer::set_modified(ArgumentMap vars, int offs, int size) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
177 |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
178 for (int i = 0; i < _arg_size; i++) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
179 if (vars.contains(i)) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
180 set_arg_modified(i, offs, size); |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
181 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
182 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
183 if (vars.contains_unknown()) |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
184 _unknown_modified = true; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
185 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
186 |
0 | 187 bool BCEscapeAnalyzer::is_recursive_call(ciMethod* callee) { |
188 for (BCEscapeAnalyzer* scope = this; scope != NULL; scope = scope->_parent) { | |
189 if (scope->method() == callee) { | |
190 return true; | |
191 } | |
192 } | |
193 return false; | |
194 } | |
195 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
196 bool BCEscapeAnalyzer::is_arg_modified(int arg, int offset, int size_in_bytes) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
197 if (offset == OFFSET_ANY) |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
198 return _arg_modified[arg] != 0; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
199 assert(arg >= 0 && arg < _arg_size, "must be an argument."); |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
200 bool modified = false; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
201 int l = offset / HeapWordSize; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
202 int h = round_to(offset + size_in_bytes, HeapWordSize) / HeapWordSize; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
203 if (l > ARG_OFFSET_MAX) |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
204 l = ARG_OFFSET_MAX; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
205 if (h > ARG_OFFSET_MAX+1) |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
206 h = ARG_OFFSET_MAX + 1; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
207 for (int i = l; i < h; i++) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
208 modified = modified || (_arg_modified[arg] & (1 << i)) != 0; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
209 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
210 return modified; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
211 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
212 |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
213 void BCEscapeAnalyzer::set_arg_modified(int arg, int offset, int size_in_bytes) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
214 if (offset == OFFSET_ANY) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
215 _arg_modified[arg] = (uint) -1; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
216 return; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
217 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
218 assert(arg >= 0 && arg < _arg_size, "must be an argument."); |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
219 int l = offset / HeapWordSize; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
220 int h = round_to(offset + size_in_bytes, HeapWordSize) / HeapWordSize; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
221 if (l > ARG_OFFSET_MAX) |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
222 l = ARG_OFFSET_MAX; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
223 if (h > ARG_OFFSET_MAX+1) |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
224 h = ARG_OFFSET_MAX + 1; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
225 for (int i = l; i < h; i++) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
226 _arg_modified[arg] |= (1 << i); |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
227 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
228 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
229 |
0 | 230 void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) { |
231 int i; | |
232 | |
233 // retrieve information about the callee | |
234 ciInstanceKlass* klass = target->holder(); | |
235 ciInstanceKlass* calling_klass = method()->holder(); | |
236 ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder); | |
237 ciInstanceKlass* actual_recv = callee_holder; | |
238 | |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
239 // Some methods are obviously bindable without any type checks so |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
240 // convert them directly to an invokespecial or invokestatic. |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
241 if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
242 switch (code) { |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
243 case Bytecodes::_invokevirtual: |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
244 code = Bytecodes::_invokespecial; |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
245 break; |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
246 case Bytecodes::_invokehandle: |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
247 code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial; |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
248 break; |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
249 } |
154
09c2ba680204
6700102: c2 assertion "counter_changed,"failed dependencies, but counter didn't change")" with AggressiveOpts
kvn
parents:
78
diff
changeset
|
250 } |
09c2ba680204
6700102: c2 assertion "counter_changed,"failed dependencies, but counter didn't change")" with AggressiveOpts
kvn
parents:
78
diff
changeset
|
251 |
0 | 252 // compute size of arguments |
3280
548597e74aa4
7030715: JSR 292 JRuby test/test_super_call_site_caching.rb asserts with +DoEscapeAnalysis
never
parents:
2165
diff
changeset
|
253 int arg_size = target->invoke_arg_size(code); |
0 | 254 int arg_base = MAX2(state._stack_height - arg_size, 0); |
255 | |
256 // direct recursive calls are skipped if they can be bound statically without introducing | |
257 // dependencies and if parameters are passed at the same position as in the current method | |
258 // other calls are skipped if there are no unescaped arguments passed to them | |
259 bool directly_recursive = (method() == target) && | |
260 (code != Bytecodes::_invokevirtual || target->is_final_method() || state._stack[arg_base] .is_empty()); | |
261 | |
262 // check if analysis of callee can safely be skipped | |
263 bool skip_callee = true; | |
264 for (i = state._stack_height - 1; i >= arg_base && skip_callee; i--) { | |
265 ArgumentMap arg = state._stack[i]; | |
266 skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base)); | |
267 } | |
2164
bb2c2878f134
7011839: JSR 292 turn on escape analysis when using invokedynamic
twisti
parents:
1972
diff
changeset
|
268 // For now we conservatively skip invokedynamic. |
bb2c2878f134
7011839: JSR 292 turn on escape analysis when using invokedynamic
twisti
parents:
1972
diff
changeset
|
269 if (code == Bytecodes::_invokedynamic) { |
bb2c2878f134
7011839: JSR 292 turn on escape analysis when using invokedynamic
twisti
parents:
1972
diff
changeset
|
270 skip_callee = true; |
bb2c2878f134
7011839: JSR 292 turn on escape analysis when using invokedynamic
twisti
parents:
1972
diff
changeset
|
271 } |
0 | 272 if (skip_callee) { |
273 TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8())); | |
274 for (i = 0; i < arg_size; i++) { | |
275 set_method_escape(state.raw_pop()); | |
276 } | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
277 _unknown_modified = true; // assume the worst since we don't analyze the called method |
0 | 278 return; |
279 } | |
280 | |
281 // determine actual method (use CHA if necessary) | |
282 ciMethod* inline_target = NULL; | |
283 if (target->is_loaded() && klass->is_loaded() | |
284 && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) | |
285 && target->will_link(klass, callee_holder, code)) { | |
286 if (code == Bytecodes::_invokestatic | |
287 || code == Bytecodes::_invokespecial | |
288 || code == Bytecodes::_invokevirtual && target->is_final_method()) { | |
289 inline_target = target; | |
290 } else { | |
291 inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv); | |
292 } | |
293 } | |
294 | |
295 if (inline_target != NULL && !is_recursive_call(inline_target)) { | |
296 // analyze callee | |
297 BCEscapeAnalyzer analyzer(inline_target, this); | |
298 | |
299 // adjust escape state of actual parameters | |
300 bool must_record_dependencies = false; | |
301 for (i = arg_size - 1; i >= 0; i--) { | |
302 ArgumentMap arg = state.raw_pop(); | |
303 if (!is_argument(arg)) | |
304 continue; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
305 for (int j = 0; j < _arg_size; j++) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
306 if (arg.contains(j)) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
307 _arg_modified[j] |= analyzer._arg_modified[i]; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
308 } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
309 } |
0 | 310 if (!is_arg_stack(arg)) { |
311 // arguments have already been recognized as escaping | |
312 } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) { | |
313 set_method_escape(arg); | |
314 must_record_dependencies = true; | |
315 } else { | |
316 set_global_escape(arg); | |
317 } | |
318 } | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
319 _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects(); |
0 | 320 |
321 // record dependencies if at least one parameter retained stack-allocatable | |
322 if (must_record_dependencies) { | |
323 if (code == Bytecodes::_invokeinterface || code == Bytecodes::_invokevirtual && !target->is_final_method()) { | |
324 _dependencies.append(actual_recv); | |
325 _dependencies.append(inline_target); | |
326 } | |
327 _dependencies.appendAll(analyzer.dependencies()); | |
328 } | |
329 } else { | |
330 TRACE_BCEA(1, tty->print_cr("[EA] virtual method %s is not monomorphic.", | |
331 target->name()->as_utf8())); | |
332 // conservatively mark all actual parameters as escaping globally | |
333 for (i = 0; i < arg_size; i++) { | |
334 ArgumentMap arg = state.raw_pop(); | |
335 if (!is_argument(arg)) | |
336 continue; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
337 set_modified(arg, OFFSET_ANY, type2size[T_INT]*HeapWordSize); |
0 | 338 set_global_escape(arg); |
339 } | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
340 _unknown_modified = true; // assume the worst since we don't know the called method |
0 | 341 } |
342 } | |
343 | |
344 bool BCEscapeAnalyzer::contains(uint arg_set1, uint arg_set2) { | |
345 return ((~arg_set1) | arg_set2) == 0; | |
346 } | |
347 | |
348 | |
349 void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, GrowableArray<ciBlock *> &successors) { | |
350 | |
351 blk->set_processed(); | |
352 ciBytecodeStream s(method()); | |
353 int limit_bci = blk->limit_bci(); | |
354 bool fall_through = false; | |
355 ArgumentMap allocated_obj; | |
356 allocated_obj.add_allocated(); | |
357 ArgumentMap unknown_obj; | |
358 unknown_obj.add_unknown(); | |
359 ArgumentMap empty_map; | |
360 | |
361 s.reset_to_bci(blk->start_bci()); | |
362 while (s.next() != ciBytecodeStream::EOBC() && s.cur_bci() < limit_bci) { | |
363 fall_through = true; | |
364 switch (s.cur_bc()) { | |
365 case Bytecodes::_nop: | |
366 break; | |
367 case Bytecodes::_aconst_null: | |
4869
5ed8f599a788
7140924: SIGSEGV in compiled code for sun.awt.X11.XDecoratedPeer.updateMinSizeHints
kvn
parents:
4122
diff
changeset
|
368 state.apush(unknown_obj); |
0 | 369 break; |
370 case Bytecodes::_iconst_m1: | |
371 case Bytecodes::_iconst_0: | |
372 case Bytecodes::_iconst_1: | |
373 case Bytecodes::_iconst_2: | |
374 case Bytecodes::_iconst_3: | |
375 case Bytecodes::_iconst_4: | |
376 case Bytecodes::_iconst_5: | |
377 case Bytecodes::_fconst_0: | |
378 case Bytecodes::_fconst_1: | |
379 case Bytecodes::_fconst_2: | |
380 case Bytecodes::_bipush: | |
381 case Bytecodes::_sipush: | |
382 state.spush(); | |
383 break; | |
384 case Bytecodes::_lconst_0: | |
385 case Bytecodes::_lconst_1: | |
386 case Bytecodes::_dconst_0: | |
387 case Bytecodes::_dconst_1: | |
388 state.lpush(); | |
389 break; | |
390 case Bytecodes::_ldc: | |
391 case Bytecodes::_ldc_w: | |
392 case Bytecodes::_ldc2_w: | |
1747
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
393 { |
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
394 // Avoid calling get_constant() which will try to allocate |
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
395 // unloaded constant. We need only constant's type. |
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
396 int index = s.get_constant_pool_index(); |
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
397 constantTag tag = s.get_constant_pool_tag(index); |
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
398 if (tag.is_long() || tag.is_double()) { |
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
399 // Only longs and doubles use 2 stack slots. |
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
400 state.lpush(); |
4869
5ed8f599a788
7140924: SIGSEGV in compiled code for sun.awt.X11.XDecoratedPeer.updateMinSizeHints
kvn
parents:
4122
diff
changeset
|
401 } else if (tag.basic_type() == T_OBJECT) { |
5ed8f599a788
7140924: SIGSEGV in compiled code for sun.awt.X11.XDecoratedPeer.updateMinSizeHints
kvn
parents:
4122
diff
changeset
|
402 state.apush(unknown_obj); |
1747
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
403 } else { |
0 | 404 state.spush(); |
405 } | |
406 break; | |
1747
53dbe853fb3a
6896381: CTW fails share/vm/ci/bcEscapeAnalyzer.cpp:99, assert(_stack_height < _max_stack,"stack overflow")
kvn
parents:
1648
diff
changeset
|
407 } |
0 | 408 case Bytecodes::_aload: |
409 state.apush(state._vars[s.get_index()]); | |
410 break; | |
411 case Bytecodes::_iload: | |
412 case Bytecodes::_fload: | |
413 case Bytecodes::_iload_0: | |
414 case Bytecodes::_iload_1: | |
415 case Bytecodes::_iload_2: | |
416 case Bytecodes::_iload_3: | |
417 case Bytecodes::_fload_0: | |
418 case Bytecodes::_fload_1: | |
419 case Bytecodes::_fload_2: | |
420 case Bytecodes::_fload_3: | |
421 state.spush(); | |
422 break; | |
423 case Bytecodes::_lload: | |
424 case Bytecodes::_dload: | |
425 case Bytecodes::_lload_0: | |
426 case Bytecodes::_lload_1: | |
427 case Bytecodes::_lload_2: | |
428 case Bytecodes::_lload_3: | |
429 case Bytecodes::_dload_0: | |
430 case Bytecodes::_dload_1: | |
431 case Bytecodes::_dload_2: | |
432 case Bytecodes::_dload_3: | |
433 state.lpush(); | |
434 break; | |
435 case Bytecodes::_aload_0: | |
436 state.apush(state._vars[0]); | |
437 break; | |
438 case Bytecodes::_aload_1: | |
439 state.apush(state._vars[1]); | |
440 break; | |
441 case Bytecodes::_aload_2: | |
442 state.apush(state._vars[2]); | |
443 break; | |
444 case Bytecodes::_aload_3: | |
445 state.apush(state._vars[3]); | |
446 break; | |
447 case Bytecodes::_iaload: | |
448 case Bytecodes::_faload: | |
449 case Bytecodes::_baload: | |
450 case Bytecodes::_caload: | |
451 case Bytecodes::_saload: | |
452 state.spop(); | |
453 set_method_escape(state.apop()); | |
454 state.spush(); | |
455 break; | |
456 case Bytecodes::_laload: | |
457 case Bytecodes::_daload: | |
458 state.spop(); | |
459 set_method_escape(state.apop()); | |
460 state.lpush(); | |
461 break; | |
462 case Bytecodes::_aaload: | |
463 { state.spop(); | |
464 ArgumentMap array = state.apop(); | |
465 set_method_escape(array); | |
466 state.apush(unknown_obj); | |
467 set_dirty(array); | |
468 } | |
469 break; | |
470 case Bytecodes::_istore: | |
471 case Bytecodes::_fstore: | |
472 case Bytecodes::_istore_0: | |
473 case Bytecodes::_istore_1: | |
474 case Bytecodes::_istore_2: | |
475 case Bytecodes::_istore_3: | |
476 case Bytecodes::_fstore_0: | |
477 case Bytecodes::_fstore_1: | |
478 case Bytecodes::_fstore_2: | |
479 case Bytecodes::_fstore_3: | |
480 state.spop(); | |
481 break; | |
482 case Bytecodes::_lstore: | |
483 case Bytecodes::_dstore: | |
484 case Bytecodes::_lstore_0: | |
485 case Bytecodes::_lstore_1: | |
486 case Bytecodes::_lstore_2: | |
487 case Bytecodes::_lstore_3: | |
488 case Bytecodes::_dstore_0: | |
489 case Bytecodes::_dstore_1: | |
490 case Bytecodes::_dstore_2: | |
491 case Bytecodes::_dstore_3: | |
492 state.lpop(); | |
493 break; | |
494 case Bytecodes::_astore: | |
495 state._vars[s.get_index()] = state.apop(); | |
496 break; | |
497 case Bytecodes::_astore_0: | |
498 state._vars[0] = state.apop(); | |
499 break; | |
500 case Bytecodes::_astore_1: | |
501 state._vars[1] = state.apop(); | |
502 break; | |
503 case Bytecodes::_astore_2: | |
504 state._vars[2] = state.apop(); | |
505 break; | |
506 case Bytecodes::_astore_3: | |
507 state._vars[3] = state.apop(); | |
508 break; | |
509 case Bytecodes::_iastore: | |
510 case Bytecodes::_fastore: | |
511 case Bytecodes::_bastore: | |
512 case Bytecodes::_castore: | |
513 case Bytecodes::_sastore: | |
514 { | |
515 state.spop(); | |
516 state.spop(); | |
517 ArgumentMap arr = state.apop(); | |
518 set_method_escape(arr); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
519 set_modified(arr, OFFSET_ANY, type2size[T_INT]*HeapWordSize); |
0 | 520 break; |
521 } | |
522 case Bytecodes::_lastore: | |
523 case Bytecodes::_dastore: | |
524 { | |
525 state.lpop(); | |
526 state.spop(); | |
527 ArgumentMap arr = state.apop(); | |
528 set_method_escape(arr); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
529 set_modified(arr, OFFSET_ANY, type2size[T_LONG]*HeapWordSize); |
0 | 530 break; |
531 } | |
532 case Bytecodes::_aastore: | |
533 { | |
534 set_global_escape(state.apop()); | |
535 state.spop(); | |
536 ArgumentMap arr = state.apop(); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
537 set_modified(arr, OFFSET_ANY, type2size[T_OBJECT]*HeapWordSize); |
0 | 538 break; |
539 } | |
540 case Bytecodes::_pop: | |
541 state.raw_pop(); | |
542 break; | |
543 case Bytecodes::_pop2: | |
544 state.raw_pop(); | |
545 state.raw_pop(); | |
546 break; | |
547 case Bytecodes::_dup: | |
548 { ArgumentMap w1 = state.raw_pop(); | |
549 state.raw_push(w1); | |
550 state.raw_push(w1); | |
551 } | |
552 break; | |
553 case Bytecodes::_dup_x1: | |
554 { ArgumentMap w1 = state.raw_pop(); | |
555 ArgumentMap w2 = state.raw_pop(); | |
556 state.raw_push(w1); | |
557 state.raw_push(w2); | |
558 state.raw_push(w1); | |
559 } | |
560 break; | |
561 case Bytecodes::_dup_x2: | |
562 { ArgumentMap w1 = state.raw_pop(); | |
563 ArgumentMap w2 = state.raw_pop(); | |
564 ArgumentMap w3 = state.raw_pop(); | |
565 state.raw_push(w1); | |
566 state.raw_push(w3); | |
567 state.raw_push(w2); | |
568 state.raw_push(w1); | |
569 } | |
570 break; | |
571 case Bytecodes::_dup2: | |
572 { ArgumentMap w1 = state.raw_pop(); | |
573 ArgumentMap w2 = state.raw_pop(); | |
574 state.raw_push(w2); | |
575 state.raw_push(w1); | |
576 state.raw_push(w2); | |
577 state.raw_push(w1); | |
578 } | |
579 break; | |
580 case Bytecodes::_dup2_x1: | |
581 { ArgumentMap w1 = state.raw_pop(); | |
582 ArgumentMap w2 = state.raw_pop(); | |
583 ArgumentMap w3 = state.raw_pop(); | |
584 state.raw_push(w2); | |
585 state.raw_push(w1); | |
586 state.raw_push(w3); | |
587 state.raw_push(w2); | |
588 state.raw_push(w1); | |
589 } | |
590 break; | |
591 case Bytecodes::_dup2_x2: | |
592 { ArgumentMap w1 = state.raw_pop(); | |
593 ArgumentMap w2 = state.raw_pop(); | |
594 ArgumentMap w3 = state.raw_pop(); | |
595 ArgumentMap w4 = state.raw_pop(); | |
596 state.raw_push(w2); | |
597 state.raw_push(w1); | |
598 state.raw_push(w4); | |
599 state.raw_push(w3); | |
600 state.raw_push(w2); | |
601 state.raw_push(w1); | |
602 } | |
603 break; | |
604 case Bytecodes::_swap: | |
605 { ArgumentMap w1 = state.raw_pop(); | |
606 ArgumentMap w2 = state.raw_pop(); | |
607 state.raw_push(w1); | |
608 state.raw_push(w2); | |
609 } | |
610 break; | |
611 case Bytecodes::_iadd: | |
612 case Bytecodes::_fadd: | |
613 case Bytecodes::_isub: | |
614 case Bytecodes::_fsub: | |
615 case Bytecodes::_imul: | |
616 case Bytecodes::_fmul: | |
617 case Bytecodes::_idiv: | |
618 case Bytecodes::_fdiv: | |
619 case Bytecodes::_irem: | |
620 case Bytecodes::_frem: | |
621 case Bytecodes::_iand: | |
622 case Bytecodes::_ior: | |
623 case Bytecodes::_ixor: | |
624 state.spop(); | |
625 state.spop(); | |
626 state.spush(); | |
627 break; | |
628 case Bytecodes::_ladd: | |
629 case Bytecodes::_dadd: | |
630 case Bytecodes::_lsub: | |
631 case Bytecodes::_dsub: | |
632 case Bytecodes::_lmul: | |
633 case Bytecodes::_dmul: | |
634 case Bytecodes::_ldiv: | |
635 case Bytecodes::_ddiv: | |
636 case Bytecodes::_lrem: | |
637 case Bytecodes::_drem: | |
638 case Bytecodes::_land: | |
639 case Bytecodes::_lor: | |
640 case Bytecodes::_lxor: | |
641 state.lpop(); | |
642 state.lpop(); | |
643 state.lpush(); | |
644 break; | |
645 case Bytecodes::_ishl: | |
646 case Bytecodes::_ishr: | |
647 case Bytecodes::_iushr: | |
648 state.spop(); | |
649 state.spop(); | |
650 state.spush(); | |
651 break; | |
652 case Bytecodes::_lshl: | |
653 case Bytecodes::_lshr: | |
654 case Bytecodes::_lushr: | |
655 state.spop(); | |
656 state.lpop(); | |
657 state.lpush(); | |
658 break; | |
659 case Bytecodes::_ineg: | |
660 case Bytecodes::_fneg: | |
661 state.spop(); | |
662 state.spush(); | |
663 break; | |
664 case Bytecodes::_lneg: | |
665 case Bytecodes::_dneg: | |
666 state.lpop(); | |
667 state.lpush(); | |
668 break; | |
669 case Bytecodes::_iinc: | |
670 break; | |
671 case Bytecodes::_i2l: | |
672 case Bytecodes::_i2d: | |
673 case Bytecodes::_f2l: | |
674 case Bytecodes::_f2d: | |
675 state.spop(); | |
676 state.lpush(); | |
677 break; | |
678 case Bytecodes::_i2f: | |
679 case Bytecodes::_f2i: | |
680 state.spop(); | |
681 state.spush(); | |
682 break; | |
683 case Bytecodes::_l2i: | |
684 case Bytecodes::_l2f: | |
685 case Bytecodes::_d2i: | |
686 case Bytecodes::_d2f: | |
687 state.lpop(); | |
688 state.spush(); | |
689 break; | |
690 case Bytecodes::_l2d: | |
691 case Bytecodes::_d2l: | |
692 state.lpop(); | |
693 state.lpush(); | |
694 break; | |
695 case Bytecodes::_i2b: | |
696 case Bytecodes::_i2c: | |
697 case Bytecodes::_i2s: | |
698 state.spop(); | |
699 state.spush(); | |
700 break; | |
701 case Bytecodes::_lcmp: | |
702 case Bytecodes::_dcmpl: | |
703 case Bytecodes::_dcmpg: | |
704 state.lpop(); | |
705 state.lpop(); | |
706 state.spush(); | |
707 break; | |
708 case Bytecodes::_fcmpl: | |
709 case Bytecodes::_fcmpg: | |
710 state.spop(); | |
711 state.spop(); | |
712 state.spush(); | |
713 break; | |
714 case Bytecodes::_ifeq: | |
715 case Bytecodes::_ifne: | |
716 case Bytecodes::_iflt: | |
717 case Bytecodes::_ifge: | |
718 case Bytecodes::_ifgt: | |
719 case Bytecodes::_ifle: | |
720 { | |
721 state.spop(); | |
722 int dest_bci = s.get_dest(); | |
723 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); | |
724 assert(s.next_bci() == limit_bci, "branch must end block"); | |
725 successors.push(_methodBlocks->block_containing(dest_bci)); | |
726 break; | |
727 } | |
728 case Bytecodes::_if_icmpeq: | |
729 case Bytecodes::_if_icmpne: | |
730 case Bytecodes::_if_icmplt: | |
731 case Bytecodes::_if_icmpge: | |
732 case Bytecodes::_if_icmpgt: | |
733 case Bytecodes::_if_icmple: | |
734 { | |
735 state.spop(); | |
736 state.spop(); | |
737 int dest_bci = s.get_dest(); | |
738 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); | |
739 assert(s.next_bci() == limit_bci, "branch must end block"); | |
740 successors.push(_methodBlocks->block_containing(dest_bci)); | |
741 break; | |
742 } | |
743 case Bytecodes::_if_acmpeq: | |
744 case Bytecodes::_if_acmpne: | |
745 { | |
746 set_method_escape(state.apop()); | |
747 set_method_escape(state.apop()); | |
748 int dest_bci = s.get_dest(); | |
749 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); | |
750 assert(s.next_bci() == limit_bci, "branch must end block"); | |
751 successors.push(_methodBlocks->block_containing(dest_bci)); | |
752 break; | |
753 } | |
754 case Bytecodes::_goto: | |
755 { | |
756 int dest_bci = s.get_dest(); | |
757 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); | |
758 assert(s.next_bci() == limit_bci, "branch must end block"); | |
759 successors.push(_methodBlocks->block_containing(dest_bci)); | |
760 fall_through = false; | |
761 break; | |
762 } | |
763 case Bytecodes::_jsr: | |
764 { | |
765 int dest_bci = s.get_dest(); | |
766 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); | |
767 assert(s.next_bci() == limit_bci, "branch must end block"); | |
768 state.apush(empty_map); | |
769 successors.push(_methodBlocks->block_containing(dest_bci)); | |
770 fall_through = false; | |
771 break; | |
772 } | |
773 case Bytecodes::_ret: | |
774 // we don't track the destination of a "ret" instruction | |
775 assert(s.next_bci() == limit_bci, "branch must end block"); | |
776 fall_through = false; | |
777 break; | |
778 case Bytecodes::_return: | |
779 assert(s.next_bci() == limit_bci, "return must end block"); | |
780 fall_through = false; | |
781 break; | |
782 case Bytecodes::_tableswitch: | |
783 { | |
784 state.spop(); | |
2142 | 785 Bytecode_tableswitch sw(&s); |
786 int len = sw.length(); | |
0 | 787 int dest_bci; |
788 for (int i = 0; i < len; i++) { | |
2142 | 789 dest_bci = s.cur_bci() + sw.dest_offset_at(i); |
0 | 790 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); |
791 successors.push(_methodBlocks->block_containing(dest_bci)); | |
792 } | |
2142 | 793 dest_bci = s.cur_bci() + sw.default_offset(); |
0 | 794 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); |
795 successors.push(_methodBlocks->block_containing(dest_bci)); | |
796 assert(s.next_bci() == limit_bci, "branch must end block"); | |
797 fall_through = false; | |
798 break; | |
799 } | |
800 case Bytecodes::_lookupswitch: | |
801 { | |
802 state.spop(); | |
2142 | 803 Bytecode_lookupswitch sw(&s); |
804 int len = sw.number_of_pairs(); | |
0 | 805 int dest_bci; |
806 for (int i = 0; i < len; i++) { | |
2142 | 807 dest_bci = s.cur_bci() + sw.pair_at(i).offset(); |
0 | 808 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); |
809 successors.push(_methodBlocks->block_containing(dest_bci)); | |
810 } | |
2142 | 811 dest_bci = s.cur_bci() + sw.default_offset(); |
0 | 812 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); |
813 successors.push(_methodBlocks->block_containing(dest_bci)); | |
814 fall_through = false; | |
815 break; | |
816 } | |
817 case Bytecodes::_ireturn: | |
818 case Bytecodes::_freturn: | |
819 state.spop(); | |
820 fall_through = false; | |
821 break; | |
822 case Bytecodes::_lreturn: | |
823 case Bytecodes::_dreturn: | |
824 state.lpop(); | |
825 fall_through = false; | |
826 break; | |
827 case Bytecodes::_areturn: | |
828 set_returned(state.apop()); | |
829 fall_through = false; | |
830 break; | |
831 case Bytecodes::_getstatic: | |
832 case Bytecodes::_getfield: | |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
833 { bool ignored_will_link; |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
834 ciField* field = s.get_field(ignored_will_link); |
0 | 835 BasicType field_type = field->type()->basic_type(); |
836 if (s.cur_bc() != Bytecodes::_getstatic) { | |
837 set_method_escape(state.apop()); | |
838 } | |
839 if (field_type == T_OBJECT || field_type == T_ARRAY) { | |
840 state.apush(unknown_obj); | |
841 } else if (type2size[field_type] == 1) { | |
842 state.spush(); | |
843 } else { | |
844 state.lpush(); | |
845 } | |
846 } | |
847 break; | |
848 case Bytecodes::_putstatic: | |
849 case Bytecodes::_putfield: | |
850 { bool will_link; | |
851 ciField* field = s.get_field(will_link); | |
852 BasicType field_type = field->type()->basic_type(); | |
853 if (field_type == T_OBJECT || field_type == T_ARRAY) { | |
854 set_global_escape(state.apop()); | |
855 } else if (type2size[field_type] == 1) { | |
856 state.spop(); | |
857 } else { | |
858 state.lpop(); | |
859 } | |
860 if (s.cur_bc() != Bytecodes::_putstatic) { | |
861 ArgumentMap p = state.apop(); | |
862 set_method_escape(p); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
863 set_modified(p, will_link ? field->offset() : OFFSET_ANY, type2size[field_type]*HeapWordSize); |
0 | 864 } |
865 } | |
866 break; | |
867 case Bytecodes::_invokevirtual: | |
868 case Bytecodes::_invokespecial: | |
869 case Bytecodes::_invokestatic: | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
196
diff
changeset
|
870 case Bytecodes::_invokedynamic: |
0 | 871 case Bytecodes::_invokeinterface: |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
872 { bool ignored_will_link; |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
873 ciSignature* declared_signature = NULL; |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
874 ciMethod* target = s.get_method(ignored_will_link, &declared_signature); |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
875 ciKlass* holder = s.get_declared_method_holder(); |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
876 assert(declared_signature != NULL, "cannot be null"); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
877 // Push appendix argument, if one. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
878 if (s.has_appendix()) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
879 state.apush(unknown_obj); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
880 } |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
881 // Pass in raw bytecode because we need to see invokehandle instructions. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4869
diff
changeset
|
882 invoke(state, s.cur_bc_raw(), target, holder); |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
883 // We are using the return type of the declared signature here because |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
884 // it might be a more concrete type than the one from the target (for |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
885 // e.g. invokedynamic and invokehandle). |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
886 ciType* return_type = declared_signature->return_type(); |
0 | 887 if (!return_type->is_primitive_type()) { |
888 state.apush(unknown_obj); | |
889 } else if (return_type->is_one_word()) { | |
890 state.spush(); | |
891 } else if (return_type->is_two_word()) { | |
892 state.lpush(); | |
893 } | |
894 } | |
895 break; | |
896 case Bytecodes::_new: | |
897 state.apush(allocated_obj); | |
898 break; | |
899 case Bytecodes::_newarray: | |
900 case Bytecodes::_anewarray: | |
901 state.spop(); | |
902 state.apush(allocated_obj); | |
903 break; | |
904 case Bytecodes::_multianewarray: | |
905 { int i = s.cur_bcp()[3]; | |
906 while (i-- > 0) state.spop(); | |
907 state.apush(allocated_obj); | |
908 } | |
909 break; | |
910 case Bytecodes::_arraylength: | |
911 set_method_escape(state.apop()); | |
912 state.spush(); | |
913 break; | |
914 case Bytecodes::_athrow: | |
915 set_global_escape(state.apop()); | |
916 fall_through = false; | |
917 break; | |
918 case Bytecodes::_checkcast: | |
919 { ArgumentMap obj = state.apop(); | |
920 set_method_escape(obj); | |
921 state.apush(obj); | |
922 } | |
923 break; | |
924 case Bytecodes::_instanceof: | |
925 set_method_escape(state.apop()); | |
926 state.spush(); | |
927 break; | |
928 case Bytecodes::_monitorenter: | |
929 case Bytecodes::_monitorexit: | |
930 state.apop(); | |
931 break; | |
932 case Bytecodes::_wide: | |
933 ShouldNotReachHere(); | |
934 break; | |
935 case Bytecodes::_ifnull: | |
936 case Bytecodes::_ifnonnull: | |
937 { | |
938 set_method_escape(state.apop()); | |
939 int dest_bci = s.get_dest(); | |
940 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); | |
941 assert(s.next_bci() == limit_bci, "branch must end block"); | |
942 successors.push(_methodBlocks->block_containing(dest_bci)); | |
943 break; | |
944 } | |
945 case Bytecodes::_goto_w: | |
946 { | |
947 int dest_bci = s.get_far_dest(); | |
948 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); | |
949 assert(s.next_bci() == limit_bci, "branch must end block"); | |
950 successors.push(_methodBlocks->block_containing(dest_bci)); | |
951 fall_through = false; | |
952 break; | |
953 } | |
954 case Bytecodes::_jsr_w: | |
955 { | |
956 int dest_bci = s.get_far_dest(); | |
957 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); | |
958 assert(s.next_bci() == limit_bci, "branch must end block"); | |
959 state.apush(empty_map); | |
960 successors.push(_methodBlocks->block_containing(dest_bci)); | |
961 fall_through = false; | |
962 break; | |
963 } | |
964 case Bytecodes::_breakpoint: | |
965 break; | |
966 default: | |
967 ShouldNotReachHere(); | |
968 break; | |
969 } | |
970 | |
971 } | |
972 if (fall_through) { | |
973 int fall_through_bci = s.cur_bci(); | |
974 if (fall_through_bci < _method->code_size()) { | |
975 assert(_methodBlocks->is_block_start(fall_through_bci), "must fall through to block start."); | |
976 successors.push(_methodBlocks->block_containing(fall_through_bci)); | |
977 } | |
978 } | |
979 } | |
980 | |
981 void BCEscapeAnalyzer::merge_block_states(StateInfo *blockstates, ciBlock *dest, StateInfo *s_state) { | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
982 StateInfo *d_state = blockstates + dest->index(); |
0 | 983 int nlocals = _method->max_locals(); |
984 | |
985 // exceptions may cause transfer of control to handlers in the middle of a | |
986 // block, so we don't merge the incoming state of exception handlers | |
987 if (dest->is_handler()) | |
988 return; | |
989 if (!d_state->_initialized ) { | |
990 // destination not initialized, just copy | |
991 for (int i = 0; i < nlocals; i++) { | |
992 d_state->_vars[i] = s_state->_vars[i]; | |
993 } | |
994 for (int i = 0; i < s_state->_stack_height; i++) { | |
995 d_state->_stack[i] = s_state->_stack[i]; | |
996 } | |
997 d_state->_stack_height = s_state->_stack_height; | |
998 d_state->_max_stack = s_state->_max_stack; | |
999 d_state->_initialized = true; | |
1000 } else if (!dest->processed()) { | |
1001 // we have not yet walked the bytecodes of dest, we can merge | |
1002 // the states | |
1003 assert(d_state->_stack_height == s_state->_stack_height, "computed stack heights must match"); | |
1004 for (int i = 0; i < nlocals; i++) { | |
1005 d_state->_vars[i].set_union(s_state->_vars[i]); | |
1006 } | |
1007 for (int i = 0; i < s_state->_stack_height; i++) { | |
1008 d_state->_stack[i].set_union(s_state->_stack[i]); | |
1009 } | |
1010 } else { | |
1011 // the bytecodes of dest have already been processed, mark any | |
1012 // arguments in the source state which are not in the dest state | |
1013 // as global escape. | |
1014 // Future refinement: we only need to mark these variable to the | |
1015 // maximum escape of any variables in dest state | |
1016 assert(d_state->_stack_height == s_state->_stack_height, "computed stack heights must match"); | |
1017 ArgumentMap extra_vars; | |
1018 for (int i = 0; i < nlocals; i++) { | |
1019 ArgumentMap t; | |
1020 t = s_state->_vars[i]; | |
1021 t.set_difference(d_state->_vars[i]); | |
1022 extra_vars.set_union(t); | |
1023 } | |
1024 for (int i = 0; i < s_state->_stack_height; i++) { | |
1025 ArgumentMap t; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1026 //extra_vars |= !d_state->_vars[i] & s_state->_vars[i]; |
0 | 1027 t.clear(); |
1028 t = s_state->_stack[i]; | |
1029 t.set_difference(d_state->_stack[i]); | |
1030 extra_vars.set_union(t); | |
1031 } | |
4122
cc81b9c09bbb
7112478: after 7105605 JRuby bench_define_method_methods.rb fails with NPE
kvn
parents:
3280
diff
changeset
|
1032 set_global_escape(extra_vars, true); |
0 | 1033 } |
1034 } | |
1035 | |
1036 void BCEscapeAnalyzer::iterate_blocks(Arena *arena) { | |
1037 int numblocks = _methodBlocks->num_blocks(); | |
1038 int stkSize = _method->max_stack(); | |
1039 int numLocals = _method->max_locals(); | |
1040 StateInfo state; | |
1041 | |
1042 int datacount = (numblocks + 1) * (stkSize + numLocals); | |
1043 int datasize = datacount * sizeof(ArgumentMap); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1044 StateInfo *blockstates = (StateInfo *) arena->Amalloc(numblocks * sizeof(StateInfo)); |
0 | 1045 ArgumentMap *statedata = (ArgumentMap *) arena->Amalloc(datasize); |
1046 for (int i = 0; i < datacount; i++) ::new ((void*)&statedata[i]) ArgumentMap(); | |
1047 ArgumentMap *dp = statedata; | |
1048 state._vars = dp; | |
1049 dp += numLocals; | |
1050 state._stack = dp; | |
1051 dp += stkSize; | |
1052 state._initialized = false; | |
1053 state._max_stack = stkSize; | |
1054 for (int i = 0; i < numblocks; i++) { | |
1055 blockstates[i]._vars = dp; | |
1056 dp += numLocals; | |
1057 blockstates[i]._stack = dp; | |
1058 dp += stkSize; | |
1059 blockstates[i]._initialized = false; | |
1060 blockstates[i]._stack_height = 0; | |
1061 blockstates[i]._max_stack = stkSize; | |
1062 } | |
1063 GrowableArray<ciBlock *> worklist(arena, numblocks / 4, 0, NULL); | |
1064 GrowableArray<ciBlock *> successors(arena, 4, 0, NULL); | |
1065 | |
1066 _methodBlocks->clear_processed(); | |
1067 | |
1068 // initialize block 0 state from method signature | |
1069 ArgumentMap allVars; // all oop arguments to method | |
1070 ciSignature* sig = method()->signature(); | |
1071 int j = 0; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1072 ciBlock* first_blk = _methodBlocks->block_containing(0); |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1073 int fb_i = first_blk->index(); |
0 | 1074 if (!method()->is_static()) { |
1075 // record information for "this" | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1076 blockstates[fb_i]._vars[j].set(j); |
0 | 1077 allVars.add(j); |
1078 j++; | |
1079 } | |
1080 for (int i = 0; i < sig->count(); i++) { | |
1081 ciType* t = sig->type_at(i); | |
1082 if (!t->is_primitive_type()) { | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1083 blockstates[fb_i]._vars[j].set(j); |
0 | 1084 allVars.add(j); |
1085 } | |
1086 j += t->size(); | |
1087 } | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1088 blockstates[fb_i]._initialized = true; |
0 | 1089 assert(j == _arg_size, "just checking"); |
1090 | |
1091 ArgumentMap unknown_map; | |
1092 unknown_map.add_unknown(); | |
1093 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1094 worklist.push(first_blk); |
0 | 1095 while(worklist.length() > 0) { |
1096 ciBlock *blk = worklist.pop(); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1097 StateInfo *blkState = blockstates + blk->index(); |
0 | 1098 if (blk->is_handler() || blk->is_ret_target()) { |
1099 // for an exception handler or a target of a ret instruction, we assume the worst case, | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1100 // that any variable could contain any argument |
0 | 1101 for (int i = 0; i < numLocals; i++) { |
1102 state._vars[i] = allVars; | |
1103 } | |
1104 if (blk->is_handler()) { | |
1105 state._stack_height = 1; | |
1106 } else { | |
1107 state._stack_height = blkState->_stack_height; | |
1108 } | |
1109 for (int i = 0; i < state._stack_height; i++) { | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1110 // ??? should this be unknown_map ??? |
0 | 1111 state._stack[i] = allVars; |
1112 } | |
1113 } else { | |
1114 for (int i = 0; i < numLocals; i++) { | |
1115 state._vars[i] = blkState->_vars[i]; | |
1116 } | |
1117 for (int i = 0; i < blkState->_stack_height; i++) { | |
1118 state._stack[i] = blkState->_stack[i]; | |
1119 } | |
1120 state._stack_height = blkState->_stack_height; | |
1121 } | |
1122 iterate_one_block(blk, state, successors); | |
1123 // if this block has any exception handlers, push them | |
1124 // onto successor list | |
1125 if (blk->has_handler()) { | |
1126 DEBUG_ONLY(int handler_count = 0;) | |
1127 int blk_start = blk->start_bci(); | |
1128 int blk_end = blk->limit_bci(); | |
1129 for (int i = 0; i < numblocks; i++) { | |
1130 ciBlock *b = _methodBlocks->block(i); | |
1131 if (b->is_handler()) { | |
1132 int ex_start = b->ex_start_bci(); | |
1133 int ex_end = b->ex_limit_bci(); | |
1134 if ((ex_start >= blk_start && ex_start < blk_end) || | |
1135 (ex_end > blk_start && ex_end <= blk_end)) { | |
1136 successors.push(b); | |
1137 } | |
1138 DEBUG_ONLY(handler_count++;) | |
1139 } | |
1140 } | |
1141 assert(handler_count > 0, "must find at least one handler"); | |
1142 } | |
1143 // merge computed variable state with successors | |
1144 while(successors.length() > 0) { | |
1145 ciBlock *succ = successors.pop(); | |
1146 merge_block_states(blockstates, succ, &state); | |
1147 if (!succ->processed()) | |
1148 worklist.push(succ); | |
1149 } | |
1150 } | |
1151 } | |
1152 | |
1153 bool BCEscapeAnalyzer::do_analysis() { | |
1154 Arena* arena = CURRENT_ENV->arena(); | |
1155 // identify basic blocks | |
1156 _methodBlocks = _method->get_method_blocks(); | |
1157 | |
1158 iterate_blocks(arena); | |
1159 // TEMPORARY | |
1160 return true; | |
1161 } | |
1162 | |
1163 vmIntrinsics::ID BCEscapeAnalyzer::known_intrinsic() { | |
1164 vmIntrinsics::ID iid = method()->intrinsic_id(); | |
1165 | |
1166 if (iid == vmIntrinsics::_getClass || | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1167 iid == vmIntrinsics::_fillInStackTrace || |
0 | 1168 iid == vmIntrinsics::_hashCode) |
1169 return iid; | |
1170 else | |
1171 return vmIntrinsics::_none; | |
1172 } | |
1173 | |
1174 bool BCEscapeAnalyzer::compute_escape_for_intrinsic(vmIntrinsics::ID iid) { | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1175 ArgumentMap arg; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1176 arg.clear(); |
0 | 1177 switch (iid) { |
1178 case vmIntrinsics::_getClass: | |
1179 _return_local = false; | |
1180 break; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1181 case vmIntrinsics::_fillInStackTrace: |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1182 arg.set(0); // 'this' |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1183 set_returned(arg); |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1184 break; |
0 | 1185 case vmIntrinsics::_hashCode: |
1186 // initialized state is correct | |
1187 break; | |
1188 default: | |
1189 assert(false, "unexpected intrinsic"); | |
1190 } | |
1191 return true; | |
1192 } | |
1193 | |
1194 void BCEscapeAnalyzer::initialize() { | |
1195 int i; | |
1196 | |
1197 // clear escape information (method may have been deoptimized) | |
1198 methodData()->clear_escape_info(); | |
1199 | |
1200 // initialize escape state of object parameters | |
1201 ciSignature* sig = method()->signature(); | |
1202 int j = 0; | |
1203 if (!method()->is_static()) { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1204 _arg_local.set(0); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1205 _arg_stack.set(0); |
0 | 1206 j++; |
1207 } | |
1208 for (i = 0; i < sig->count(); i++) { | |
1209 ciType* t = sig->type_at(i); | |
1210 if (!t->is_primitive_type()) { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1211 _arg_local.set(j); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1212 _arg_stack.set(j); |
0 | 1213 } |
1214 j += t->size(); | |
1215 } | |
1216 assert(j == _arg_size, "just checking"); | |
1217 | |
1218 // start with optimistic assumption | |
1219 ciType *rt = _method->return_type(); | |
1220 if (rt->is_primitive_type()) { | |
1221 _return_local = false; | |
1222 _return_allocated = false; | |
1223 } else { | |
1224 _return_local = true; | |
1225 _return_allocated = true; | |
1226 } | |
1227 _allocated_escapes = false; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1228 _unknown_modified = false; |
0 | 1229 } |
1230 | |
1231 void BCEscapeAnalyzer::clear_escape_info() { | |
1232 ciSignature* sig = method()->signature(); | |
1233 int arg_count = sig->count(); | |
1234 ArgumentMap var; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1235 if (!method()->is_static()) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1236 arg_count++; // allow for "this" |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1237 } |
0 | 1238 for (int i = 0; i < arg_count; i++) { |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1239 set_arg_modified(i, OFFSET_ANY, 4); |
0 | 1240 var.clear(); |
1241 var.set(i); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1242 set_modified(var, OFFSET_ANY, 4); |
0 | 1243 set_global_escape(var); |
1244 } | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1245 _arg_local.Clear(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1246 _arg_stack.Clear(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1247 _arg_returned.Clear(); |
0 | 1248 _return_local = false; |
1249 _return_allocated = false; | |
1250 _allocated_escapes = true; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1251 _unknown_modified = true; |
0 | 1252 } |
1253 | |
1254 | |
1255 void BCEscapeAnalyzer::compute_escape_info() { | |
1256 int i; | |
1257 assert(!methodData()->has_escape_info(), "do not overwrite escape info"); | |
1258 | |
1259 vmIntrinsics::ID iid = known_intrinsic(); | |
1260 | |
1261 // check if method can be analyzed | |
1262 if (iid == vmIntrinsics::_none && (method()->is_abstract() || method()->is_native() || !method()->holder()->is_initialized() | |
1263 || _level > MaxBCEAEstimateLevel | |
1264 || method()->code_size() > MaxBCEAEstimateSize)) { | |
1265 if (BCEATraceLevel >= 1) { | |
1266 tty->print("Skipping method because: "); | |
1267 if (method()->is_abstract()) | |
1268 tty->print_cr("method is abstract."); | |
1269 else if (method()->is_native()) | |
1270 tty->print_cr("method is native."); | |
1271 else if (!method()->holder()->is_initialized()) | |
1272 tty->print_cr("class of method is not initialized."); | |
1273 else if (_level > MaxBCEAEstimateLevel) | |
1274 tty->print_cr("level (%d) exceeds MaxBCEAEstimateLevel (%d).", | |
1275 _level, MaxBCEAEstimateLevel); | |
1276 else if (method()->code_size() > MaxBCEAEstimateSize) | |
1277 tty->print_cr("code size (%d) exceeds MaxBCEAEstimateSize.", | |
1278 method()->code_size(), MaxBCEAEstimateSize); | |
1279 else | |
1280 ShouldNotReachHere(); | |
1281 } | |
1282 clear_escape_info(); | |
1283 | |
1284 return; | |
1285 } | |
1286 | |
1287 if (BCEATraceLevel >= 1) { | |
1288 tty->print("[EA] estimating escape information for"); | |
1289 if (iid != vmIntrinsics::_none) | |
1290 tty->print(" intrinsic"); | |
1291 method()->print_short_name(); | |
1292 tty->print_cr(" (%d bytes)", method()->code_size()); | |
1293 } | |
1294 | |
1295 bool success; | |
1296 | |
1297 initialize(); | |
1298 | |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1299 // Do not scan method if it has no object parameters and |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1300 // does not returns an object (_return_allocated is set in initialize()). |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1301 if (_arg_local.Size() == 0 && !_return_allocated) { |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1302 // Clear all info since method's bytecode was not analysed and |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1303 // set pessimistic escape information. |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1304 clear_escape_info(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1305 methodData()->set_eflag(MethodData::allocated_escapes); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1306 methodData()->set_eflag(MethodData::unknown_modified); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1307 methodData()->set_eflag(MethodData::estimated); |
0 | 1308 return; |
1309 } | |
1310 | |
1311 if (iid != vmIntrinsics::_none) | |
1312 success = compute_escape_for_intrinsic(iid); | |
1313 else { | |
1314 success = do_analysis(); | |
1315 } | |
1316 | |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1317 // don't store interprocedural escape information if it introduces |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1318 // dependencies or if method data is empty |
0 | 1319 // |
1320 if (!has_dependencies() && !methodData()->is_empty()) { | |
1321 for (i = 0; i < _arg_size; i++) { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1322 if (_arg_local.test(i)) { |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1323 assert(_arg_stack.test(i), "inconsistent escape info"); |
0 | 1324 methodData()->set_arg_local(i); |
1325 methodData()->set_arg_stack(i); | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1326 } else if (_arg_stack.test(i)) { |
0 | 1327 methodData()->set_arg_stack(i); |
1328 } | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1329 if (_arg_returned.test(i)) { |
0 | 1330 methodData()->set_arg_returned(i); |
1331 } | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1332 methodData()->set_arg_modified(i, _arg_modified[i]); |
0 | 1333 } |
1334 if (_return_local) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1335 methodData()->set_eflag(MethodData::return_local); |
0 | 1336 } |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1337 if (_return_allocated) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1338 methodData()->set_eflag(MethodData::return_allocated); |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1339 } |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1340 if (_allocated_escapes) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1341 methodData()->set_eflag(MethodData::allocated_escapes); |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1342 } |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1343 if (_unknown_modified) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1344 methodData()->set_eflag(MethodData::unknown_modified); |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1345 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1346 methodData()->set_eflag(MethodData::estimated); |
0 | 1347 } |
1348 } | |
1349 | |
1350 void BCEscapeAnalyzer::read_escape_info() { | |
1351 assert(methodData()->has_escape_info(), "no escape info available"); | |
1352 | |
1353 // read escape information from method descriptor | |
1354 for (int i = 0; i < _arg_size; i++) { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1355 if (methodData()->is_arg_local(i)) |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1356 _arg_local.set(i); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1357 if (methodData()->is_arg_stack(i)) |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1358 _arg_stack.set(i); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1359 if (methodData()->is_arg_returned(i)) |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1360 _arg_returned.set(i); |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1361 _arg_modified[i] = methodData()->arg_modified(i); |
0 | 1362 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1363 _return_local = methodData()->eflag_set(MethodData::return_local); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1364 _return_allocated = methodData()->eflag_set(MethodData::return_allocated); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1365 _allocated_escapes = methodData()->eflag_set(MethodData::allocated_escapes); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
1366 _unknown_modified = methodData()->eflag_set(MethodData::unknown_modified); |
0 | 1367 |
1368 } | |
1369 | |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1370 #ifndef PRODUCT |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1371 void BCEscapeAnalyzer::dump() { |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1372 tty->print("[EA] estimated escape information for"); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1373 method()->print_short_name(); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1374 tty->print_cr(has_dependencies() ? " (not stored)" : ""); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1375 tty->print(" non-escaping args: "); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1376 _arg_local.print_on(tty); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1377 tty->print(" stack-allocatable args: "); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1378 _arg_stack.print_on(tty); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1379 if (_return_local) { |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1380 tty->print(" returned args: "); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1381 _arg_returned.print_on(tty); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1382 } else if (is_return_allocated()) { |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1383 tty->print_cr(" return allocated value"); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1384 } else { |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1385 tty->print_cr(" return non-local value"); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1386 } |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1387 tty->print(" modified args: "); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1388 for (int i = 0; i < _arg_size; i++) { |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1389 if (_arg_modified[i] == 0) |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1390 tty->print(" 0"); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1391 else |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1392 tty->print(" 0x%x", _arg_modified[i]); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1393 } |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1394 tty->cr(); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1395 tty->print(" flags: "); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1396 if (_return_allocated) |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1397 tty->print(" return_allocated"); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1398 if (_allocated_escapes) |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1399 tty->print(" allocated_escapes"); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1400 if (_unknown_modified) |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1401 tty->print(" unknown_modified"); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1402 tty->cr(); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1403 } |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1404 #endif |
0 | 1405 |
1406 BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) | |
1407 : _conservative(method == NULL || !EstimateArgEscape) | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1408 , _arena(CURRENT_ENV->arena()) |
0 | 1409 , _method(method) |
1410 , _methodData(method ? method->method_data() : NULL) | |
1411 , _arg_size(method ? method->arg_size() : 0) | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1412 , _arg_local(_arena) |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1413 , _arg_stack(_arena) |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1414 , _arg_returned(_arena) |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1415 , _dirty(_arena) |
0 | 1416 , _return_local(false) |
1417 , _return_allocated(false) | |
1418 , _allocated_escapes(false) | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1419 , _unknown_modified(false) |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1420 , _dependencies(_arena, 4, 0, NULL) |
0 | 1421 , _parent(parent) |
1422 , _level(parent == NULL ? 0 : parent->level() + 1) { | |
1423 if (!_conservative) { | |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1424 _arg_local.Clear(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1425 _arg_stack.Clear(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1426 _arg_returned.Clear(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1427 _dirty.Clear(); |
0 | 1428 Arena* arena = CURRENT_ENV->arena(); |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1429 _arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint)); |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
1430 Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint)); |
0 | 1431 |
1432 if (methodData() == NULL) | |
1433 return; | |
1434 bool printit = _method->should_print_assembly(); | |
1435 if (methodData()->has_escape_info()) { | |
1436 TRACE_BCEA(2, tty->print_cr("[EA] Reading previous results for %s.%s", | |
1437 method->holder()->name()->as_utf8(), | |
1438 method->name()->as_utf8())); | |
1439 read_escape_info(); | |
1440 } else { | |
1441 TRACE_BCEA(2, tty->print_cr("[EA] computing results for %s.%s", | |
1442 method->holder()->name()->as_utf8(), | |
1443 method->name()->as_utf8())); | |
1444 | |
1445 compute_escape_info(); | |
1446 methodData()->update_escape_info(); | |
1447 } | |
78
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1448 #ifndef PRODUCT |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1449 if (BCEATraceLevel >= 3) { |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1450 // dump escape information |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1451 dump(); |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1452 } |
e1e86702e43e
6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents:
45
diff
changeset
|
1453 #endif |
0 | 1454 } |
1455 } | |
1456 | |
1457 void BCEscapeAnalyzer::copy_dependencies(Dependencies *deps) { | |
1397
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
844
diff
changeset
|
1458 if (ciEnv::current()->jvmti_can_hotswap_or_post_breakpoint()) { |
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
844
diff
changeset
|
1459 // Also record evol dependencies so redefinition of the |
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
844
diff
changeset
|
1460 // callee will trigger recompilation. |
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
844
diff
changeset
|
1461 deps->assert_evol_method(method()); |
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
844
diff
changeset
|
1462 } |
0 | 1463 for (int i = 0; i < _dependencies.length(); i+=2) { |
1648
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1464 ciKlass *k = _dependencies.at(i)->as_klass(); |
8099e71601df
6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies
kvn
parents:
1552
diff
changeset
|
1465 ciMethod *m = _dependencies.at(i+1)->as_method(); |
0 | 1466 deps->assert_unique_concrete_method(k, m); |
1467 } | |
1468 } |