annotate src/share/vm/runtime/frame.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 d2ede61b7a12
children da877bdc9000
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: 1513
diff changeset
2 * Copyright (c) 1997, 2010, 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: 1513
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1513
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: 1513
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 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_frame.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 RegisterMap::RegisterMap(JavaThread *thread, bool update_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
29 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 _update_map = update_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
32 debug_only(_update_for_id = NULL;)
a61af66fc99e Initial load
duke
parents:
diff changeset
33 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
34 for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
35 #endif /* PRODUCT */
a61af66fc99e Initial load
duke
parents:
diff changeset
36 }
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 RegisterMap::RegisterMap(const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 assert(map != this, "bad initialization parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
40 assert(map != NULL, "RegisterMap must be present");
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _thread = map->thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _update_map = map->update_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _include_argument_oops = map->include_argument_oops();
a61af66fc99e Initial load
duke
parents:
diff changeset
44 debug_only(_update_for_id = map->_update_for_id;)
a61af66fc99e Initial load
duke
parents:
diff changeset
45 pd_initialize_from(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
46 if (update_map()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 for(int i = 0; i < location_valid_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 LocationValidType bits = !update_map() ? 0 : map->_location_valid[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
49 _location_valid[i] = bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // for whichever bits are set, pull in the corresponding map->_location
a61af66fc99e Initial load
duke
parents:
diff changeset
51 int j = i*location_valid_type_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 while (bits != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 if ((bits & 1) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 assert(0 <= j && j < reg_count, "range check");
a61af66fc99e Initial load
duke
parents:
diff changeset
55 _location[j] = map->_location[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 bits >>= 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 j += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 void RegisterMap::clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 set_include_argument_oops(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
66 if (_update_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
67 for(int i = 0; i < location_valid_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 _location_valid[i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 pd_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
71 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 pd_initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
73 }
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 void RegisterMap::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 st->print_cr("Register map");
a61af66fc99e Initial load
duke
parents:
diff changeset
80 for(int i = 0; i < reg_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 VMReg r = VMRegImpl::as_VMReg(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 intptr_t* src = (intptr_t*) location(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if (src != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85
417
f4fe12e429a4 6764622: IdealGraphVisualizer fixes
never
parents: 196
diff changeset
86 r->print_on(st);
f4fe12e429a4 6764622: IdealGraphVisualizer fixes
never
parents: 196
diff changeset
87 st->print(" [" INTPTR_FORMAT "] = ", src);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
88 if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
417
f4fe12e429a4 6764622: IdealGraphVisualizer fixes
never
parents: 196
diff changeset
89 st->print_cr("<misaligned>");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
90 } else {
417
f4fe12e429a4 6764622: IdealGraphVisualizer fixes
never
parents: 196
diff changeset
91 st->print_cr(INTPTR_FORMAT, *src);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void RegisterMap::print() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 print_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // This returns the pc that if you were in the debugger you'd see. Not
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // the idealized value in the frame object. This undoes the magic conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // that happens for deoptimized frames. In addition it makes the value the
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // hardware would want to see in the native frame. The only user (at this point)
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // is deoptimization. It likely no one else should ever use it.
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 address frame::raw_pc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if (is_deoptimized_frame()) {
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
110 nmethod* nm = cb()->as_nmethod_or_null();
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
111 if (nm->is_method_handle_return(pc()))
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
112 return nm->deopt_mh_handler_begin() - pc_return_offset;
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
113 else
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
114 return nm->deopt_handler_begin() - pc_return_offset;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
115 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 return (pc() - pc_return_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // Change the pc in a frame object. This does not change the actual pc in
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // actual frame. To do that use patch_pc.
a61af66fc99e Initial load
duke
parents:
diff changeset
122 //
a61af66fc99e Initial load
duke
parents:
diff changeset
123 void frame::set_pc(address newpc ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
125 if (_cb != NULL && _cb->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant violation");
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // Unsafe to use the is_deoptimzed tester after changing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
131 _deopt_state = unknown;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 _pc = newpc;
a61af66fc99e Initial load
duke
parents:
diff changeset
133 _cb = CodeCache::find_blob_unsafe(_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // type testers
a61af66fc99e Initial load
duke
parents:
diff changeset
138 bool frame::is_deoptimized_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 assert(_deopt_state != unknown, "not answerable");
a61af66fc99e Initial load
duke
parents:
diff changeset
140 return _deopt_state == is_deoptimized;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 bool frame::is_native_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 return (_cb != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
145 _cb->is_nmethod() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
146 ((nmethod*)_cb)->is_native_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 bool frame::is_java_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (is_interpreted_frame()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 if (is_compiled_frame()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 bool frame::is_compiled_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 if (_cb != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
158 _cb->is_nmethod() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
159 ((nmethod*)_cb)->is_java_method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 bool frame::is_runtime_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 return (_cb != NULL && _cb->is_runtime_stub());
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 bool frame::is_safepoint_blob_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 return (_cb != NULL && _cb->is_safepoint_stub());
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // testers
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 bool frame::is_first_java_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 RegisterMap map(JavaThread::current(), false); // No update
a61af66fc99e Initial load
duke
parents:
diff changeset
178 frame s;
a61af66fc99e Initial load
duke
parents:
diff changeset
179 for (s = sender(&map); !(s.is_java_frame() || s.is_first_frame()); s = s.sender(&map));
a61af66fc99e Initial load
duke
parents:
diff changeset
180 return s.is_first_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 bool frame::entry_frame_is_first() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return entry_frame_call_wrapper()->anchor()->last_Java_sp() == NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 bool frame::should_be_deoptimized() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (_deopt_state == is_deoptimized ||
a61af66fc99e Initial load
duke
parents:
diff changeset
191 !is_compiled_frame() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 assert(_cb != NULL && _cb->is_nmethod(), "must be an nmethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
193 nmethod* nm = (nmethod *)_cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if (TraceDependencies) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 tty->print("checking (%s) ", nm->is_marked_for_deoptimization() ? "true" : "false");
a61af66fc99e Initial load
duke
parents:
diff changeset
196 nm->print_value_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 if( !nm->is_marked_for_deoptimization() )
a61af66fc99e Initial load
duke
parents:
diff changeset
201 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // If at the return point, then the frame has already been popped, and
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // only the return needs to be executed. Don't deoptimize here.
a61af66fc99e Initial load
duke
parents:
diff changeset
205 return !nm->is_at_poll_return(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 bool frame::can_be_deoptimized() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (!is_compiled_frame()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 nmethod* nm = (nmethod*)_cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 if( !nm->can_be_deoptimized() )
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 return !nm->is_at_poll_return(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 void frame::deoptimize(JavaThread* thread, bool thread_is_known_safe) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // Schedule deoptimization of an nmethod activation with this frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // Store the original pc before an patch (or request to self-deopt)
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // in the published location of the frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 assert(_cb != NULL && _cb->is_nmethod(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
225 nmethod* nm = (nmethod*)_cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
226
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // This is a fix for register window patching race
a61af66fc99e Initial load
duke
parents:
diff changeset
228 if (NeedsDeoptSuspend && !thread_is_known_safe) {
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // It is possible especially with DeoptimizeALot/DeoptimizeRandom that
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // we could see the frame again and ask for it to be deoptimized since
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // it might move for a long time. That is harmless and we just ignore it.
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if (id() == thread->must_deopt_id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 assert(thread->is_deopt_suspend(), "lost suspension");
a61af66fc99e Initial load
duke
parents:
diff changeset
235 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // We are at a safepoint so the target thread can only be
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // in 4 states:
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // blocked - no problem
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // blocked_trans - no problem (i.e. could have woken up from blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // during a safepoint).
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // native - register window pc patching race
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // native_trans - momentary state
a61af66fc99e Initial load
duke
parents:
diff changeset
245 //
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // We could just wait out a thread in native_trans to block.
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // Then we'd have all the issues that the safepoint code has as to
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // whether to spin or block. It isn't worth it. Just treat it like
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // native and be done with it.
a61af66fc99e Initial load
duke
parents:
diff changeset
250 //
a61af66fc99e Initial load
duke
parents:
diff changeset
251 JavaThreadState state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if (state == _thread_in_native || state == _thread_in_native_trans) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // Since we are at a safepoint the target thread will stop itself
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // before it can return to java as long as we remain at the safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // Therefore we can put an additional request for the thread to stop
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // no matter what no (like a suspend). This will cause the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // to notice it needs to do the deopt on its own once it leaves native.
a61af66fc99e Initial load
duke
parents:
diff changeset
258 //
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // The only reason we must do this is because on machine with register
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // windows we have a race with patching the return address and the
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // window coming live as the thread returns to the Java code (but still
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // in native mode) and then blocks. It is only this top most frame
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // that is at risk. So in truth we could add an additional check to
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // see if this frame is one that is at risk.
a61af66fc99e Initial load
duke
parents:
diff changeset
265 RegisterMap map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 frame at_risk = thread->last_frame().sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if (id() == at_risk.id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 thread->set_must_deopt_id(id());
a61af66fc99e Initial load
duke
parents:
diff changeset
269 thread->set_deopt_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
270 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
273 } // NeedsDeoptSuspend
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
276 // If the call site is a MethodHandle call site use the MH deopt
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
277 // handler.
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
278 address deopt = nm->is_method_handle_return(pc()) ?
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
279 nm->deopt_mh_handler_begin() :
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
280 nm->deopt_handler_begin();
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
281
0
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Save the original pc before we patch in the new one
a61af66fc99e Initial load
duke
parents:
diff changeset
283 nm->set_original_pc(this, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
284 patch_pc(thread, deopt);
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
285
0
a61af66fc99e Initial load
duke
parents:
diff changeset
286 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
287 {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 RegisterMap map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
289 frame check = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
290 while (id() != check.id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 check = check.sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
293 assert(check.is_deoptimized_frame(), "missed deopt");
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 frame frame::java_sender() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 RegisterMap map(JavaThread::current(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 frame s;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 for (s = sender(&map); !(s.is_java_frame() || s.is_first_frame()); s = s.sender(&map)) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 guarantee(s.is_java_frame(), "tried to get caller of first java frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
303 return s;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 frame frame::real_sender(RegisterMap* map) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 frame result = sender(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 while (result.is_runtime_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 result = result.sender(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // Note: called by profiler - NOT for current thread
a61af66fc99e Initial load
duke
parents:
diff changeset
315 frame frame::profile_find_Java_sender_frame(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // If we don't recognize this frame, walk back up the stack until we do
a61af66fc99e Initial load
duke
parents:
diff changeset
317 RegisterMap map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 frame first_java_frame = frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // Find the first Java frame on the stack starting with input frame
a61af66fc99e Initial load
duke
parents:
diff changeset
321 if (is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // top frame is compiled frame or deoptimized frame
a61af66fc99e Initial load
duke
parents:
diff changeset
323 first_java_frame = *this;
a61af66fc99e Initial load
duke
parents:
diff changeset
324 } else if (safe_for_sender(thread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 for (frame sender_frame = sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
326 sender_frame.safe_for_sender(thread) && !sender_frame.is_first_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
327 sender_frame = sender_frame.sender(&map)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (sender_frame.is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 first_java_frame = sender_frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334 return first_java_frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // Interpreter frames
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 void frame::interpreter_frame_set_locals(intptr_t* locs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
341 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
342 *interpreter_frame_locals_addr() = locs;
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 methodOop frame::interpreter_frame_method() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
346 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
347 methodOop m = *interpreter_frame_method_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
348 assert(m->is_perm(), "bad methodOop in interpreter frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
349 assert(m->is_method(), "not a methodOop");
a61af66fc99e Initial load
duke
parents:
diff changeset
350 return m;
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352
a61af66fc99e Initial load
duke
parents:
diff changeset
353 void frame::interpreter_frame_set_method(methodOop method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
354 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
355 *interpreter_frame_method_addr() = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 void frame::interpreter_frame_set_bcx(intptr_t bcx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
360 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
361 bool formerly_bci = is_bci(interpreter_frame_bcx());
a61af66fc99e Initial load
duke
parents:
diff changeset
362 bool is_now_bci = is_bci(bcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
363 *interpreter_frame_bcx_addr() = bcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 intptr_t mdx = interpreter_frame_mdx();
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 if (mdx != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 if (formerly_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 if (!is_now_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // The bcx was just converted from bci to bcp.
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // Convert the mdx in parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
372 methodDataOop mdo = interpreter_frame_method()->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
373 assert(mdo != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
374 int mdi = mdx - 1; // We distinguish valid mdi from zero by adding one.
a61af66fc99e Initial load
duke
parents:
diff changeset
375 address mdp = mdo->di_to_dp(mdi);
a61af66fc99e Initial load
duke
parents:
diff changeset
376 interpreter_frame_set_mdx((intptr_t)mdp);
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 if (is_now_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // The bcx was just converted from bcp to bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // Convert the mdx in parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
382 methodDataOop mdo = interpreter_frame_method()->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
383 assert(mdo != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
384 int mdi = mdo->dp_to_di((address)mdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
385 interpreter_frame_set_mdx((intptr_t)mdi + 1); // distinguish valid from 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 *interpreter_frame_bcx_addr() = bcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393
a61af66fc99e Initial load
duke
parents:
diff changeset
394 jint frame::interpreter_frame_bci() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
396 intptr_t bcx = interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
397 return is_bci(bcx) ? bcx : interpreter_frame_method()->bci_from((address)bcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 void frame::interpreter_frame_set_bci(jint bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
401 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
402 assert(!is_bci(interpreter_frame_bcx()), "should not set bci during GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
403 interpreter_frame_set_bcx((intptr_t)interpreter_frame_method()->bcp_from(bci));
a61af66fc99e Initial load
duke
parents:
diff changeset
404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 address frame::interpreter_frame_bcp() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
408 intptr_t bcx = interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
409 return is_bci(bcx) ? interpreter_frame_method()->bcp_from(bcx) : (address)bcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 void frame::interpreter_frame_set_bcp(address bcp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
414 assert(!is_bci(interpreter_frame_bcx()), "should not set bcp during GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
415 interpreter_frame_set_bcx((intptr_t)bcp);
a61af66fc99e Initial load
duke
parents:
diff changeset
416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 void frame::interpreter_frame_set_mdx(intptr_t mdx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
420 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
421 *interpreter_frame_mdx_addr() = mdx;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 address frame::interpreter_frame_mdp() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
426 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
427 intptr_t bcx = interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
428 intptr_t mdx = interpreter_frame_mdx();
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 assert(!is_bci(bcx), "should not access mdp during GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
431 return (address)mdx;
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 void frame::interpreter_frame_set_mdp(address mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
435 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if (mdp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // Always allow the mdp to be cleared.
a61af66fc99e Initial load
duke
parents:
diff changeset
438 interpreter_frame_set_mdx((intptr_t)mdp);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440 intptr_t bcx = interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
441 assert(!is_bci(bcx), "should not set mdp during GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
442 interpreter_frame_set_mdx((intptr_t)mdp);
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444
a61af66fc99e Initial load
duke
parents:
diff changeset
445 BasicObjectLock* frame::next_monitor_in_interpreter_frame(BasicObjectLock* current) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
446 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
447 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
448 interpreter_frame_verify_monitor(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
450 BasicObjectLock* next = (BasicObjectLock*) (((intptr_t*) current) + interpreter_frame_monitor_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
451 return next;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 BasicObjectLock* frame::previous_monitor_in_interpreter_frame(BasicObjectLock* current) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
456 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // // This verification needs to be checked before being enabled
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // interpreter_frame_verify_monitor(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
459 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
460 BasicObjectLock* previous = (BasicObjectLock*) (((intptr_t*) current) - interpreter_frame_monitor_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
461 return previous;
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // Interpreter locals and expression stack locations.
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 intptr_t* frame::interpreter_frame_local_at(int index) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 const int n = Interpreter::local_offset_in_bytes(index)/wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
468 return &((*interpreter_frame_locals_addr())[n]);
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471 intptr_t* frame::interpreter_frame_expression_stack_at(jint offset) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 const int i = offset * interpreter_frame_expression_stack_direction();
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
473 const int n = i * Interpreter::stackElementWords;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
474 return &(interpreter_frame_expression_stack()[n]);
a61af66fc99e Initial load
duke
parents:
diff changeset
475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
476
a61af66fc99e Initial load
duke
parents:
diff changeset
477 jint frame::interpreter_frame_expression_stack_size() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // Number of elements on the interpreter expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // Callers should span by stackElementWords
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
480 int element_size = Interpreter::stackElementWords;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
481 if (frame::interpreter_frame_expression_stack_direction() < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
482 return (interpreter_frame_expression_stack() -
a61af66fc99e Initial load
duke
parents:
diff changeset
483 interpreter_frame_tos_address() + 1)/element_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
484 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 return (interpreter_frame_tos_address() -
a61af66fc99e Initial load
duke
parents:
diff changeset
486 interpreter_frame_expression_stack() + 1)/element_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // (frame::interpreter_frame_sender_sp accessor is in frame_<arch>.cpp)
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493 const char* frame::print_name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (is_native_frame()) return "Native";
a61af66fc99e Initial load
duke
parents:
diff changeset
495 if (is_interpreted_frame()) return "Interpreted";
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (is_compiled_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if (is_deoptimized_frame()) return "Deoptimized";
a61af66fc99e Initial load
duke
parents:
diff changeset
498 return "Compiled";
a61af66fc99e Initial load
duke
parents:
diff changeset
499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
500 if (sp() == NULL) return "Empty";
a61af66fc99e Initial load
duke
parents:
diff changeset
501 return "C";
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 void frame::print_value_on(outputStream* st, JavaThread *thread) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 NOT_PRODUCT(address begin = pc()-40;)
a61af66fc99e Initial load
duke
parents:
diff changeset
506 NOT_PRODUCT(address end = NULL;)
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp());
a61af66fc99e Initial load
duke
parents:
diff changeset
509 if (sp() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
510 st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 if (StubRoutines::contains(pc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 st->print_cr(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
514 st->print("(");
a61af66fc99e Initial load
duke
parents:
diff changeset
515 StubCodeDesc* desc = StubCodeDesc::desc_for(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
516 st->print("~Stub::%s", desc->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
517 NOT_PRODUCT(begin = desc->begin(); end = desc->end();)
a61af66fc99e Initial load
duke
parents:
diff changeset
518 } else if (Interpreter::contains(pc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 st->print_cr(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
520 st->print("(");
a61af66fc99e Initial load
duke
parents:
diff changeset
521 InterpreterCodelet* desc = Interpreter::codelet_containing(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
522 if (desc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
523 st->print("~");
a61af66fc99e Initial load
duke
parents:
diff changeset
524 desc->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
525 NOT_PRODUCT(begin = desc->code_begin(); end = desc->code_end();)
a61af66fc99e Initial load
duke
parents:
diff changeset
526 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 st->print("~interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
530 st->print_cr(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if (_cb != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
534 _cb->print_value_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
535 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
536 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if (end == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
538 begin = _cb->instructions_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
539 end = _cb->instructions_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 NOT_PRODUCT(if (WizardMode && Verbose) Disassembler::decode(begin, end);)
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 void frame::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
548 print_value_on(st,NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 if (is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
550 interpreter_frame_print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 void frame::interpreter_frame_print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
556 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
557 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
558 jint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
559 for (i = 0; i < interpreter_frame_method()->max_locals(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 intptr_t x = *interpreter_frame_local_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 st->print(" - local [" INTPTR_FORMAT "]", x);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 st->fill_to(23);
a61af66fc99e Initial load
duke
parents:
diff changeset
563 st->print_cr("; #%d", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
565 for (i = interpreter_frame_expression_stack_size() - 1; i >= 0; --i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 intptr_t x = *interpreter_frame_expression_stack_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
567 st->print(" - stack [" INTPTR_FORMAT "]", x);
a61af66fc99e Initial load
duke
parents:
diff changeset
568 st->fill_to(23);
a61af66fc99e Initial load
duke
parents:
diff changeset
569 st->print_cr("; #%d", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // locks for synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
572 for (BasicObjectLock* current = interpreter_frame_monitor_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
573 current < interpreter_frame_monitor_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
574 current = next_monitor_in_interpreter_frame(current)) {
1255
e3a4305c6bc3 6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents: 1204
diff changeset
575 st->print(" - obj [");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
576 current->obj()->print_value_on(st);
1255
e3a4305c6bc3 6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents: 1204
diff changeset
577 st->print_cr("]");
e3a4305c6bc3 6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents: 1204
diff changeset
578 st->print(" - lock [");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
579 current->lock()->print_on(st);
1255
e3a4305c6bc3 6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents: 1204
diff changeset
580 st->print_cr("]");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
583 st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin());
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // bcp
a61af66fc99e Initial load
duke
parents:
diff changeset
585 st->print(" - bcp [" INTPTR_FORMAT "]", interpreter_frame_bcp());
a61af66fc99e Initial load
duke
parents:
diff changeset
586 st->fill_to(23);
a61af66fc99e Initial load
duke
parents:
diff changeset
587 st->print_cr("; @%d", interpreter_frame_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // locals
a61af66fc99e Initial load
duke
parents:
diff changeset
589 st->print_cr(" - locals [" INTPTR_FORMAT "]", interpreter_frame_local_at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // method
a61af66fc99e Initial load
duke
parents:
diff changeset
591 st->print(" - method [" INTPTR_FORMAT "]", (address)interpreter_frame_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
592 st->fill_to(23);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 st->print("; ");
a61af66fc99e Initial load
duke
parents:
diff changeset
594 interpreter_frame_method()->print_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
595 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
596 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // Return whether the frame is in the VM or os indicating a Hotspot problem.
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // Otherwise, it's likely a bug in the native library that the Java code calls,
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // hopefully indicating where to submit bugs.
a61af66fc99e Initial load
duke
parents:
diff changeset
602 static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // C/C++ frame
a61af66fc99e Initial load
duke
parents:
diff changeset
604 bool in_vm = os::address_is_in_vm(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
605 st->print(in_vm ? "V" : "C");
a61af66fc99e Initial load
duke
parents:
diff changeset
606
a61af66fc99e Initial load
duke
parents:
diff changeset
607 int offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
608 bool found;
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // libname
a61af66fc99e Initial load
duke
parents:
diff changeset
611 found = os::dll_address_to_library_name(pc, buf, buflen, &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
612 if (found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // skip directory names
a61af66fc99e Initial load
duke
parents:
diff changeset
614 const char *p1, *p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
615 p1 = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
616 int len = (int)strlen(os::file_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
617 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
a61af66fc99e Initial load
duke
parents:
diff changeset
618 st->print(" [%s+0x%x]", p1, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
619 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 st->print(" " PTR_FORMAT, pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // function name - os::dll_address_to_function_name() may return confusing
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // names if pc is within jvm.dll or libjvm.so, because JVM only has
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // JVM_xxxx and a few other symbols in the dynamic symbol table. Do this
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // only for native libraries.
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if (!in_vm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 found = os::dll_address_to_function_name(pc, buf, buflen, &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 if (found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 st->print(" %s+0x%x", buf, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // frame::print_on_error() is called by fatal error handler. Notice that we may
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // crash inside this function if stack frame is corrupted. The fatal error
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // handler can catch and handle the crash. Here we assume the frame is valid.
a61af66fc99e Initial load
duke
parents:
diff changeset
639 //
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // First letter indicates type of the frame:
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // J: Java frame (compiled)
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // j: Java frame (interpreted)
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // V: VM frame (C/C++)
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // v: Other frames running VM generated code (e.g. stubs, adapters, etc.)
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // C: C/C++ frame
a61af66fc99e Initial load
duke
parents:
diff changeset
646 //
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // We don't need detailed frame type as that in frame::print_name(). "C"
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // suggests the problem is in user lib; everything else is likely a VM bug.
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 if (_cb != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 if (Interpreter::contains(pc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 methodOop m = this->interpreter_frame_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
654 if (m != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 m->name_and_sig_as_C_string(buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
656 st->print("j %s", buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
657 st->print("+%d", this->interpreter_frame_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
658 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 st->print("j " PTR_FORMAT, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661 } else if (StubRoutines::contains(pc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
662 StubCodeDesc* desc = StubCodeDesc::desc_for(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
663 if (desc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
664 st->print("v ~StubRoutines::%s", desc->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
665 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
666 st->print("v ~StubRoutines::" PTR_FORMAT, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
667 }
a61af66fc99e Initial load
duke
parents:
diff changeset
668 } else if (_cb->is_buffer_blob()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
669 st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
670 } else if (_cb->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
671 methodOop m = ((nmethod *)_cb)->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
672 if (m != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 m->name_and_sig_as_C_string(buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
674 st->print("J %s", buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
675 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 st->print("J " PTR_FORMAT, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
678 } else if (_cb->is_runtime_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
679 st->print("v ~RuntimeStub::%s", ((RuntimeStub *)_cb)->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
680 } else if (_cb->is_deoptimization_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
681 st->print("v ~DeoptimizationBlob");
a61af66fc99e Initial load
duke
parents:
diff changeset
682 } else if (_cb->is_exception_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 st->print("v ~ExceptionBlob");
a61af66fc99e Initial load
duke
parents:
diff changeset
684 } else if (_cb->is_safepoint_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
685 st->print("v ~SafepointBlob");
a61af66fc99e Initial load
duke
parents:
diff changeset
686 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 st->print("v blob " PTR_FORMAT, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
689 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 print_C_frame(st, buf, buflen, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694
a61af66fc99e Initial load
duke
parents:
diff changeset
695 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
696 The interpreter_frame_expression_stack_at method in the case of SPARC needs the
a61af66fc99e Initial load
duke
parents:
diff changeset
697 max_stack value of the method in order to compute the expression stack address.
a61af66fc99e Initial load
duke
parents:
diff changeset
698 It uses the methodOop in order to get the max_stack value but during GC this
a61af66fc99e Initial load
duke
parents:
diff changeset
699 methodOop value saved on the frame is changed by reverse_and_push and hence cannot
a61af66fc99e Initial load
duke
parents:
diff changeset
700 be used. So we save the max_stack value in the FrameClosure object and pass it
a61af66fc99e Initial load
duke
parents:
diff changeset
701 down to the interpreter_frame_expression_stack_at method
a61af66fc99e Initial load
duke
parents:
diff changeset
702 */
a61af66fc99e Initial load
duke
parents:
diff changeset
703 class InterpreterFrameClosure : public OffsetClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
705 frame* _fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
706 OopClosure* _f;
a61af66fc99e Initial load
duke
parents:
diff changeset
707 int _max_locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
708 int _max_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
711 InterpreterFrameClosure(frame* fr, int max_locals, int max_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
712 OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
713 _fr = fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
714 _max_locals = max_locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 _max_stack = max_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
716 _f = f;
a61af66fc99e Initial load
duke
parents:
diff changeset
717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719 void offset_do(int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 oop* addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if (offset < _max_locals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 addr = (oop*) _fr->interpreter_frame_local_at(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
723 assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
724 _f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
726 addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals));
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // In case of exceptions, the expression stack is invalid and the esp will be reset to express
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel).
a61af66fc99e Initial load
duke
parents:
diff changeset
729 bool in_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
730 if (frame::interpreter_frame_expression_stack_direction() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
732 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
733 in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if (in_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 _f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 int max_locals() { return _max_locals; }
a61af66fc99e Initial load
duke
parents:
diff changeset
742 frame* fr() { return _fr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
743 };
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 class InterpretedArgumentOopFinder: public SignatureInfo {
a61af66fc99e Initial load
duke
parents:
diff changeset
747 private:
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
748 OopClosure* _f; // Closure to invoke
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
749 int _offset; // TOS-relative offset, decremented with each argument
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
750 bool _has_receiver; // true if the callee has a receiver
0
a61af66fc99e Initial load
duke
parents:
diff changeset
751 frame* _fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 void set(int size, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
754 _offset -= size;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 if (type == T_OBJECT || type == T_ARRAY) oop_offset_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 void oop_offset_do() {
a61af66fc99e Initial load
duke
parents:
diff changeset
759 oop* addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
760 addr = (oop*)_fr->interpreter_frame_tos_at(_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
761 _f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 public:
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
765 InterpretedArgumentOopFinder(symbolHandle signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureInfo(signature), _has_receiver(has_receiver) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // compute size of arguments
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
767 int args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
768 assert(!fr->is_interpreted_frame() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
769 args_size <= fr->interpreter_frame_expression_stack_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
770 "args cannot be on stack anymore");
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // initialize InterpretedArgumentOopFinder
a61af66fc99e Initial load
duke
parents:
diff changeset
772 _f = f;
a61af66fc99e Initial load
duke
parents:
diff changeset
773 _fr = fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
774 _offset = args_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 void oops_do() {
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
778 if (_has_receiver) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
779 --_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
780 oop_offset_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
782 iterate_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
784 };
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // Entry frame has following form (n arguments)
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // +-----------+
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // sp -> | last arg |
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // +-----------+
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // : ::: :
a61af66fc99e Initial load
duke
parents:
diff changeset
792 // +-----------+
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // (sp+n)->| first arg|
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // +-----------+
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798 // visits and GC's all the arguments in entry frame
a61af66fc99e Initial load
duke
parents:
diff changeset
799 class EntryFrameOopFinder: public SignatureInfo {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
801 bool _is_static;
a61af66fc99e Initial load
duke
parents:
diff changeset
802 int _offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 frame* _fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
804 OopClosure* _f;
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 void set(int size, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
807 assert (_offset >= 0, "illegal offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if (type == T_OBJECT || type == T_ARRAY) oop_at_offset_do(_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
809 _offset -= size;
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 void oop_at_offset_do(int offset) {
1489
cff162798819 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 1255
diff changeset
813 assert (offset >= 0, "illegal offset");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
814 oop* addr = (oop*) _fr->entry_frame_argument_at(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
815 _f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
819 EntryFrameOopFinder(frame* frame, symbolHandle signature, bool is_static) : SignatureInfo(signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
820 _f = NULL; // will be set later
a61af66fc99e Initial load
duke
parents:
diff changeset
821 _fr = frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
822 _is_static = is_static;
a61af66fc99e Initial load
duke
parents:
diff changeset
823 _offset = ArgumentSizeComputer(signature).size() - 1; // last parameter is at index 0
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 void arguments_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
827 _f = f;
a61af66fc99e Initial load
duke
parents:
diff changeset
828 if (!_is_static) oop_at_offset_do(_offset+1); // do the receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
829 iterate_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
831
a61af66fc99e Initial load
duke
parents:
diff changeset
832 };
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 oop* frame::interpreter_callee_receiver_addr(symbolHandle signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
835 ArgumentSizeComputer asc(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
836 int size = asc.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
837 return (oop *)interpreter_frame_tos_at(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
839
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
842 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
843 assert(map != NULL, "map must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
844 Thread *thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
845 methodHandle m (thread, interpreter_frame_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
846 jint bci = interpreter_frame_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
847
a61af66fc99e Initial load
duke
parents:
diff changeset
848 assert(Universe::heap()->is_in(m()), "must be valid oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
849 assert(m->is_method(), "checking frame value");
a61af66fc99e Initial load
duke
parents:
diff changeset
850 assert((m->is_native() && bci == 0) || (!m->is_native() && bci >= 0 && bci < m->code_size()), "invalid bci value");
a61af66fc99e Initial load
duke
parents:
diff changeset
851
a61af66fc99e Initial load
duke
parents:
diff changeset
852 // Handle the monitor elements in the activation
a61af66fc99e Initial load
duke
parents:
diff changeset
853 for (
a61af66fc99e Initial load
duke
parents:
diff changeset
854 BasicObjectLock* current = interpreter_frame_monitor_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
855 current < interpreter_frame_monitor_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
856 current = next_monitor_in_interpreter_frame(current)
a61af66fc99e Initial load
duke
parents:
diff changeset
857 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
859 interpreter_frame_verify_monitor(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
860 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
861 current->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // process fixed part
a61af66fc99e Initial load
duke
parents:
diff changeset
865 f->do_oop((oop*)interpreter_frame_method_addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
866 f->do_oop((oop*)interpreter_frame_cache_addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // Hmm what about the mdp?
a61af66fc99e Initial load
duke
parents:
diff changeset
869 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // Interpreter frame in the midst of a call have a methodOop within the
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // object.
a61af66fc99e Initial load
duke
parents:
diff changeset
872 interpreterState istate = get_interpreterState();
a61af66fc99e Initial load
duke
parents:
diff changeset
873 if (istate->msg() == BytecodeInterpreter::call_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
874 f->do_oop((oop*)&istate->_result._to_call._callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
878
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1552
diff changeset
879 #ifndef PPC
0
a61af66fc99e Initial load
duke
parents:
diff changeset
880 if (m->is_native()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
881 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
882 f->do_oop((oop*)&istate->_oop_temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
883 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
884 f->do_oop((oop*)( fp() + interpreter_frame_oop_temp_offset ));
a61af66fc99e Initial load
duke
parents:
diff changeset
885 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
886 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1552
diff changeset
887 #else // PPC
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1552
diff changeset
888 if (m->is_native() && m->is_static()) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1552
diff changeset
889 f->do_oop(interpreter_frame_mirror_addr());
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1552
diff changeset
890 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1552
diff changeset
891 #endif // PPC
0
a61af66fc99e Initial load
duke
parents:
diff changeset
892
a61af66fc99e Initial load
duke
parents:
diff changeset
893 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
894
a61af66fc99e Initial load
duke
parents:
diff changeset
895 symbolHandle signature;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
896 bool has_receiver = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
897
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // Process a callee's arguments if we are at a call site
a61af66fc99e Initial load
duke
parents:
diff changeset
899 // (i.e., if we are at an invoke bytecode)
a61af66fc99e Initial load
duke
parents:
diff changeset
900 // This is used sometimes for calling into the VM, not for another
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // interpreted or compiled frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
902 if (!m->is_native()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 Bytecode_invoke *call = Bytecode_invoke_at_check(m, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 if (call != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
905 signature = symbolHandle(thread, call->signature());
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
906 has_receiver = call->has_receiver();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (map->include_argument_oops() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
908 interpreter_frame_expression_stack_size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 ResourceMark rm(thread); // is this right ???
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // we are at a call site & the expression stack is not empty
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // => process callee's arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
912 //
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // Note: The expression stack can be empty if an exception
605
98cb887364d3 6810672: Comment typos
twisti
parents: 417
diff changeset
914 // occurred during method resolution/execution. In all
0
a61af66fc99e Initial load
duke
parents:
diff changeset
915 // cases we empty the expression stack completely be-
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // fore handling the exception (the exception handling
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // code in the interpreter calls a blocking runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
918 // routine which can cause this code to be executed).
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // (was bug gri 7/27/98)
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
920 oops_interpreted_arguments_do(signature, has_receiver, f);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
925 InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f);
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
926
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
927 // process locals & expression stack
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
928 InterpreterOopMap mask;
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
929 if (query_oop_map_cache) {
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
930 m->mask_for(bci, &mask);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
931 } else {
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
932 OopMapCache::compute_one_oop_map(m, bci, &mask);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
934 mask.iterate_oop(&blk);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
936
a61af66fc99e Initial load
duke
parents:
diff changeset
937
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
938 void frame::oops_interpreted_arguments_do(symbolHandle signature, bool has_receiver, OopClosure* f) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
939 InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
940 finder.oops_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 605
diff changeset
943 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
944 assert(_cb != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
945 if (_cb->oop_maps() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
946 OopMapSet::oops_do(this, reg_map, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
947
a61af66fc99e Initial load
duke
parents:
diff changeset
948 // Preserve potential arguments for a callee. We handle this by dispatching
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // on the codeblob. For c2i, we do
a61af66fc99e Initial load
duke
parents:
diff changeset
950 if (reg_map->include_argument_oops()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
951 _cb->preserve_callee_argument_oops(*this, reg_map, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // In cases where perm gen is collected, GC will want to mark
a61af66fc99e Initial load
duke
parents:
diff changeset
955 // oops referenced from nmethods active on thread stacks so as to
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // prevent them from being collected. However, this visit should be
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // restricted to certain phases of the collection only. The
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 605
diff changeset
958 // closure decides how it wants nmethods to be traced.
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 605
diff changeset
959 if (cf != NULL)
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 605
diff changeset
960 cf->do_code_blob(_cb);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
962
a61af66fc99e Initial load
duke
parents:
diff changeset
963 class CompiledArgumentOopFinder: public SignatureInfo {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
965 OopClosure* _f;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
966 int _offset; // the current offset, incremented with each argument
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
967 bool _has_receiver; // true if the callee has a receiver
0
a61af66fc99e Initial load
duke
parents:
diff changeset
968 frame _fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
969 RegisterMap* _reg_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
970 int _arg_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
971 VMRegPair* _regs; // VMReg list of arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
972
a61af66fc99e Initial load
duke
parents:
diff changeset
973 void set(int size, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
974 if (type == T_OBJECT || type == T_ARRAY) handle_oop_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
975 _offset += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 virtual void handle_oop_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // Extract low order register number from register array.
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // In LP64-land, the high-order bits are valid but unhelpful.
a61af66fc99e Initial load
duke
parents:
diff changeset
981 VMReg reg = _regs[_offset].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
982 oop *loc = _fr.oopmapreg_to_location(reg, _reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
983 _f->do_oop(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985
a61af66fc99e Initial load
duke
parents:
diff changeset
986 public:
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
987 CompiledArgumentOopFinder(symbolHandle signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
988 : SignatureInfo(signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // initialize CompiledArgumentOopFinder
a61af66fc99e Initial load
duke
parents:
diff changeset
991 _f = f;
a61af66fc99e Initial load
duke
parents:
diff changeset
992 _offset = 0;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
993 _has_receiver = has_receiver;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
994 _fr = fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
995 _reg_map = (RegisterMap*)reg_map;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
996 _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998 int arg_size;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
999 _regs = SharedRuntime::find_callee_arguments(signature(), has_receiver, &arg_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 assert(arg_size == _arg_size, "wrong arg size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 void oops_do() {
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
1004 if (_has_receiver) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 handle_oop_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 _offset++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 iterate_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1011
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
1012 void frame::oops_compiled_arguments_do(symbolHandle signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 ResourceMark rm;
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 989
diff changeset
1014 CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 finder.oops_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
a61af66fc99e Initial load
duke
parents:
diff changeset
1018
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // Get receiver out of callers frame, i.e. find parameter 0 in callers
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // frame. Consult ADLC for where parameter 0 is to be found. Then
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // check local reg_map for it being a callee-save register or argument
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // register, both of which are saved in the local frame. If not found
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // there, it must be an in-stack argument of the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // Note: caller.sp() points to callee-arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 oop frame::retrieve_receiver(RegisterMap* reg_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 frame caller = *this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // First consult the ADLC on where it puts parameter 0 for this signature.
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 VMReg reg = SharedRuntime::name_for_receiver();
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 oop r = *caller.oopmapreg_to_location(reg, reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 assert( Universe::heap()->is_in_or_null(r), "bad receiver" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 return r;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 oop* frame::oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 if(reg->is_reg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // If it is passed in a register, it got spilled in the stub frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 return (oop *)reg_map->location(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 } else {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1041 int sp_offset_in_bytes = reg->reg2stack() * VMRegImpl::stack_slot_size;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1042 return (oop*)(((address)unextended_sp()) + sp_offset_in_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1045
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 BasicLock* frame::compiled_synchronized_native_monitor(nmethod* nm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 if (nm == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 assert(_cb != NULL && _cb->is_nmethod() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 nm->method()->is_native() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 nm->method()->is_synchronized(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 "should not call this otherwise");
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 nm = (nmethod*) _cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_sp_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 assert(byte_offset >= 0, "should not see invalid offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 return (BasicLock*) &sp()[byte_offset / wordSize];
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1058
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 oop frame::compiled_synchronized_native_monitor_owner(nmethod* nm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 if (nm == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 assert(_cb != NULL && _cb->is_nmethod() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 nm->method()->is_native() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 nm->method()->is_synchronized(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 "should not call this otherwise");
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 nm = (nmethod*) _cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_owner_sp_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 assert(byte_offset >= 0, "should not see invalid offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 oop owner = ((oop*) sp())[byte_offset / wordSize];
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 assert( Universe::heap()->is_in(owner), "bad receiver" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 return owner;
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 void frame::oops_entry_do(OopClosure* f, const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 assert(map != NULL, "map must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 if (map->include_argument_oops()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // must collect argument oops, as nobody else is doing it
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 Thread *thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 methodHandle m (thread, entry_frame_call_wrapper()->callee_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 symbolHandle signature (thread, m->signature());
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 EntryFrameOopFinder finder(this, signature, m->is_static());
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 finder.arguments_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 // Traverse the Handle Block saved in the entry frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 entry_frame_call_wrapper()->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 605
diff changeset
1089 void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
1119
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1090 #ifndef PRODUCT
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1091 // simulate GC crash here to dump java thread in error report
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1092 if (CrashGCForDumpingJavaThread) {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1093 char *t = NULL;
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1094 *t = 'c';
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1095 }
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1096 #endif
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1097 if (is_interpreted_frame()) {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1098 oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1099 } else if (is_entry_frame()) {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1100 oops_entry_do(f, map);
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1101 } else if (CodeCache::contains(pc())) {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 989
diff changeset
1102 oops_code_blob_do(f, cf, map);
1692
d2ede61b7a12 6976186: integrate Shark HotSpot changes
twisti
parents: 1681
diff changeset
1103 #ifdef SHARK
d2ede61b7a12 6976186: integrate Shark HotSpot changes
twisti
parents: 1681
diff changeset
1104 } else if (is_fake_stub_frame()) {
d2ede61b7a12 6976186: integrate Shark HotSpot changes
twisti
parents: 1681
diff changeset
1105 // nothing to do
d2ede61b7a12 6976186: integrate Shark HotSpot changes
twisti
parents: 1681
diff changeset
1106 #endif // SHARK
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 605
diff changeset
1112 void frame::nmethods_do(CodeBlobClosure* cf) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 if (_cb != NULL && _cb->is_nmethod()) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 605
diff changeset
1114 cf->do_code_blob(_cb);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 void frame::gc_prologue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 if (is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // set bcx to bci to become methodOop position independent during GC
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 interpreter_frame_set_bcx(interpreter_frame_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 void frame::gc_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 if (is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // set bcx back to bcp for interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 interpreter_frame_set_bcx((intptr_t)interpreter_frame_bcp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // call processor specific epilog function
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 pd_gc_epilog();
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 # ifdef ENABLE_ZAP_DEAD_LOCALS
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 void frame::CheckValueClosure::do_oop(oop* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 if (CheckOopishValues && Universe::heap()->is_in_reserved(*p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 warning("value @ " INTPTR_FORMAT " looks oopish (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current());
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 frame::CheckValueClosure frame::_check_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1145
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 void frame::CheckOopClosure::do_oop(oop* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 if (*p != NULL && !(*p)->is_oop()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 warning("value @ " INTPTR_FORMAT " should be an oop (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current());
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 frame::CheckOopClosure frame::_check_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1153
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 void frame::check_derived_oop(oop* base, oop* derived) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 _check_oop.do_oop(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1157
a61af66fc99e Initial load
duke
parents:
diff changeset
1158
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 void frame::ZapDeadClosure::do_oop(oop* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 if (TraceZapDeadLocals) tty->print_cr("zapping @ " INTPTR_FORMAT " containing " INTPTR_FORMAT, p, (address)*p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // Need cast because on _LP64 the conversion to oop is ambiguous. Constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // can be either long or int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 *p = (oop)(int)0xbabebabe;
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 frame::ZapDeadClosure frame::_zap_dead;
a61af66fc99e Initial load
duke
parents:
diff changeset
1166
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 void frame::zap_dead_locals(JavaThread* thread, const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 assert(thread == Thread::current(), "need to synchronize to do this to another thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // Tracing - part 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 if (TraceZapDeadLocals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 tty->print_cr("--------------------------------------------------------------------------------");
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 tty->print("Zapping dead locals in ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 print_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // Zapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 if (is_entry_frame ()) zap_dead_entry_locals (thread, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 else if (is_interpreted_frame()) zap_dead_interpreted_locals(thread, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 else if (is_compiled_frame()) zap_dead_compiled_locals (thread, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 // could be is_runtime_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 // so remove error: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 // Tracing - part 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 if (TraceZapDeadLocals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1191
a61af66fc99e Initial load
duke
parents:
diff changeset
1192
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // get current interpreter 'pc'
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 methodOop m = interpreter_frame_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 int bci = interpreter_frame_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
1198
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
1200
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1201 // process dynamic part
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1202 InterpreterFrameClosure value_blk(this, max_locals, m->max_stack(),
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1203 &_check_value);
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1204 InterpreterFrameClosure oop_blk(this, max_locals, m->max_stack(),
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1205 &_check_oop );
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1206 InterpreterFrameClosure dead_blk(this, max_locals, m->max_stack(),
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1207 &_zap_dead );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1208
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1209 // get frame map
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1210 InterpreterOopMap mask;
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1211 m->mask_for(bci, &mask);
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1255
diff changeset
1212 mask.iterate_all( &oop_blk, &value_blk, &dead_blk);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1214
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 void frame::zap_dead_compiled_locals(JavaThread* thread, const RegisterMap* reg_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 assert(_cb != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 if (_cb->oop_maps() != NULL) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1221 OopMapSet::all_do(this, reg_map, &_check_oop, check_derived_oop, &_check_value);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1224
a61af66fc99e Initial load
duke
parents:
diff changeset
1225
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 void frame::zap_dead_entry_locals(JavaThread*, const RegisterMap*) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 if (TraceZapDeadLocals) warning("frame::zap_dead_entry_locals unimplemented");
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1229
a61af66fc99e Initial load
duke
parents:
diff changeset
1230
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 void frame::zap_dead_deoptimized_locals(JavaThread*, const RegisterMap*) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 if (TraceZapDeadLocals) warning("frame::zap_dead_deoptimized_locals unimplemented");
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 # endif // ENABLE_ZAP_DEAD_LOCALS
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 void frame::verify(const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // for now make sure receiver type is correct
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 if (is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 methodOop method = interpreter_frame_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 guarantee(method->is_method(), "method is wrong in frame::verify");
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 if (!method->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // fetch the receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 oop* p = (oop*) interpreter_frame_local_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 // make sure we have the right receiver type
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), "must be empty before verify");)
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 605
diff changeset
1249 oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1251
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 bool frame::verify_return_pc(address x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 if (StubRoutines::returns_to_call_stub(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 if (CodeCache::contains(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 if (Interpreter::contains(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1267
a61af66fc99e Initial load
duke
parents:
diff changeset
1268
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 void frame::interpreter_frame_verify_monitor(BasicObjectLock* value) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 // verify that the value is in the right part of the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 address low_mark = (address) interpreter_frame_monitor_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 address high_mark = (address) interpreter_frame_monitor_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 address current = (address) value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 const int monitor_size = frame::interpreter_frame_monitor_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 guarantee((high_mark - current) % monitor_size == 0 , "Misaligned top of BasicObjectLock*");
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 guarantee( high_mark > current , "Current BasicObjectLock* higher than high_mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
1280
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 guarantee((current - low_mark) % monitor_size == 0 , "Misaligned bottom of BasicObjectLock*");
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 guarantee( current >= low_mark , "Current BasicObjectLock* below than low_mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1285
a61af66fc99e Initial load
duke
parents:
diff changeset
1286
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 //-----------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // StackFrameStream implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
1289
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 StackFrameStream::StackFrameStream(JavaThread *thread, bool update) : _reg_map(thread, update) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 assert(thread->has_last_Java_frame(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 _fr = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 _is_done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 }