Mercurial > hg > truffle
annotate src/cpu/x86/vm/frame_x86.cpp @ 2007:5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Thu, 02 Dec 2010 17:21:12 -0800 |
parents | f95d63e2154a |
children | 06f017f7daa7 2e038ad0c1d0 |
rev | line source |
---|---|
0 | 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 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
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 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "interpreter/interpreter.hpp" | |
27 #include "memory/resourceArea.hpp" | |
28 #include "oops/markOop.hpp" | |
29 #include "oops/methodOop.hpp" | |
30 #include "oops/oop.inline.hpp" | |
31 #include "runtime/frame.inline.hpp" | |
32 #include "runtime/handles.inline.hpp" | |
33 #include "runtime/javaCalls.hpp" | |
34 #include "runtime/monitorChunk.hpp" | |
35 #include "runtime/signature.hpp" | |
36 #include "runtime/stubCodeGenerator.hpp" | |
37 #include "runtime/stubRoutines.hpp" | |
38 #include "vmreg_x86.inline.hpp" | |
39 #ifdef COMPILER1 | |
40 #include "c1/c1_Runtime1.hpp" | |
41 #include "runtime/vframeArray.hpp" | |
42 #endif | |
0 | 43 |
44 #ifdef ASSERT | |
45 void RegisterMap::check_location_valid() { | |
46 } | |
47 #endif | |
48 | |
49 | |
50 // Profiling/safepoint support | |
51 | |
52 bool frame::safe_for_sender(JavaThread *thread) { | |
53 address sp = (address)_sp; | |
54 address fp = (address)_fp; | |
55 address unextended_sp = (address)_unextended_sp; | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
56 // sp must be within the stack |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
57 bool sp_safe = (sp <= thread->stack_base()) && |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
58 (sp >= thread->stack_base() - thread->stack_size()); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
59 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
60 if (!sp_safe) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
61 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
62 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
63 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
64 // unextended sp must be within the stack and above or equal sp |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
65 bool unextended_sp_safe = (unextended_sp <= thread->stack_base()) && |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
66 (unextended_sp >= sp); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
67 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
68 if (!unextended_sp_safe) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
69 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
70 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
71 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
72 // an fp must be within the stack and above (but not equal) sp |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
73 bool fp_safe = (fp <= thread->stack_base()) && (fp > sp); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
74 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
75 // We know sp/unextended_sp are safe only fp is questionable here |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
76 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
77 // If the current frame is known to the code cache then we can attempt to |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
78 // to construct the sender and do some validation of it. This goes a long way |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
79 // toward eliminating issues when we get in frame construction code |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
80 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
81 if (_cb != NULL ) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
82 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
83 // First check if frame is complete and tester is reliable |
0 | 84 // Unfortunately we can only check frame complete for runtime stubs and nmethod |
85 // other generic buffer blobs are more problematic so we just assume they are | |
86 // ok. adapter blobs never have a frame complete and are never ok. | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
87 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
88 if (!_cb->is_frame_complete_at(_pc)) { |
0 | 89 if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { |
90 return false; | |
91 } | |
92 } | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
93 // Entry frame checks |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
94 if (is_entry_frame()) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
95 // an entry frame must have a valid fp. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
96 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
97 if (!fp_safe) return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
98 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
99 // Validate the JavaCallWrapper an entry frame must have |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
100 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
101 address jcw = (address)entry_frame_call_wrapper(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
102 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
103 bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > fp); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
104 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
105 return jcw_safe; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
106 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
107 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
108 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
109 intptr_t* sender_sp = NULL; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
110 address sender_pc = NULL; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
111 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
112 if (is_interpreted_frame()) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
113 // fp must be safe |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
114 if (!fp_safe) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
115 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
116 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
117 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
118 sender_pc = (address) this->fp()[return_addr_offset]; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
119 sender_sp = (intptr_t*) addr_at(sender_sp_offset); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
120 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
121 } else { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
122 // must be some sort of compiled/runtime frame |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
123 // fp does not have to be safe (although it could be check for c1?) |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
124 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
125 sender_sp = _unextended_sp + _cb->frame_size(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
126 // On Intel the return_address is always the word on the stack |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
127 sender_pc = (address) *(sender_sp-1); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
128 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
129 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
130 // We must always be able to find a recognizable pc |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
131 CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
132 if (sender_pc == NULL || sender_blob == NULL) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
133 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
134 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
135 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
136 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
137 // If the potential sender is the interpreter then we can do some more checking |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
138 if (Interpreter::contains(sender_pc)) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
139 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
140 // ebp is always saved in a recognizable place in any code we generate. However |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
141 // only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved ebp |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
142 // is really a frame pointer. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
143 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
144 intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
145 bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
146 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
147 if (!saved_fp_safe) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
148 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
149 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
150 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
151 // construct the potential sender |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
152 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
153 frame sender(sender_sp, saved_fp, sender_pc); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
154 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
155 return sender.is_interpreted_frame_valid(thread); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
156 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
157 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
158 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
159 // Could just be some random pointer within the codeBlob |
1748 | 160 if (!sender_blob->code_contains(sender_pc)) { |
161 return false; | |
162 } | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
163 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
164 // We should never be able to see an adapter if the current frame is something from code cache |
1748 | 165 if (sender_blob->is_adapter_blob()) { |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
166 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
167 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
168 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
169 // Could be the call_stub |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
170 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
171 if (StubRoutines::returns_to_call_stub(sender_pc)) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
172 intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
173 bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
174 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
175 if (!saved_fp_safe) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
176 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
177 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
178 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
179 // construct the potential sender |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
180 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
181 frame sender(sender_sp, saved_fp, sender_pc); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
182 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
183 // Validate the JavaCallWrapper an entry frame must have |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
184 address jcw = (address)sender.entry_frame_call_wrapper(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
185 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
186 bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > (address)sender.fp()); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
187 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
188 return jcw_safe; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
189 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
190 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
191 // If the frame size is 0 something is bad because every nmethod has a non-zero frame size |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
192 // because the return address counts against the callee's frame. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
193 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
194 if (sender_blob->frame_size() == 0) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
195 assert(!sender_blob->is_nmethod(), "should count return address at least"); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
196 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
197 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
198 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
199 // We should never be able to see anything here except an nmethod. If something in the |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
200 // code cache (current frame) is called by an entity within the code cache that entity |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
201 // should not be anything but the call stub (already covered), the interpreter (already covered) |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
202 // or an nmethod. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
203 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
204 assert(sender_blob->is_nmethod(), "Impossible call chain"); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
205 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
206 // Could put some more validation for the potential non-interpreted sender |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
207 // frame we'd create by calling sender if I could think of any. Wait for next crash in forte... |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
208 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
209 // One idea is seeing if the sender_pc we have is one that we'd expect to call to current cb |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
210 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
211 // We've validated the potential sender that would be created |
0 | 212 return true; |
213 } | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
214 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
215 // Must be native-compiled frame. Since sender will try and use fp to find |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
216 // linkages it must be safe |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
217 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
218 if (!fp_safe) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
219 return false; |
0 | 220 } |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
221 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
222 // Will the pc we fetch be non-zero (which we'll find at the oldest frame) |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
223 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
224 if ( (address) this->fp()[return_addr_offset] == NULL) return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
225 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
226 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
227 // could try and do some more potential verification of native frame if we could think of some... |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
228 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
229 return true; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
230 |
0 | 231 } |
232 | |
233 | |
234 void frame::patch_pc(Thread* thread, address pc) { | |
235 if (TracePcPatching) { | |
304 | 236 tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ", |
237 &((address *)sp())[-1], ((address *)sp())[-1], pc); | |
0 | 238 } |
239 ((address *)sp())[-1] = pc; | |
240 _cb = CodeCache::find_blob(pc); | |
1204 | 241 address original_pc = nmethod::get_deopt_original_pc(this); |
242 if (original_pc != NULL) { | |
243 assert(original_pc == _pc, "expected original PC to be stored before patching"); | |
0 | 244 _deopt_state = is_deoptimized; |
245 // leave _pc as is | |
246 } else { | |
247 _deopt_state = not_deoptimized; | |
248 _pc = pc; | |
249 } | |
250 } | |
251 | |
252 bool frame::is_interpreted_frame() const { | |
253 return Interpreter::contains(pc()); | |
254 } | |
255 | |
793
eacd97c88873
6848466: frame::frame_size() assertion failure with -XX:+DebugDeoptimization
cfang
parents:
304
diff
changeset
|
256 int frame::frame_size(RegisterMap* map) const { |
eacd97c88873
6848466: frame::frame_size() assertion failure with -XX:+DebugDeoptimization
cfang
parents:
304
diff
changeset
|
257 frame sender = this->sender(map); |
0 | 258 return sender.sp() - sp(); |
259 } | |
260 | |
261 intptr_t* frame::entry_frame_argument_at(int offset) const { | |
262 // convert offset to index to deal with tsi | |
263 int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize); | |
264 // Entry frame's arguments are always in relation to unextended_sp() | |
265 return &unextended_sp()[index]; | |
266 } | |
267 | |
268 // sender_sp | |
269 #ifdef CC_INTERP | |
270 intptr_t* frame::interpreter_frame_sender_sp() const { | |
271 assert(is_interpreted_frame(), "interpreted frame expected"); | |
272 // QQQ why does this specialize method exist if frame::sender_sp() does same thing? | |
273 // seems odd and if we always know interpreted vs. non then sender_sp() is really | |
274 // doing too much work. | |
275 return get_interpreterState()->sender_sp(); | |
276 } | |
277 | |
278 // monitor elements | |
279 | |
280 BasicObjectLock* frame::interpreter_frame_monitor_begin() const { | |
281 return get_interpreterState()->monitor_base(); | |
282 } | |
283 | |
284 BasicObjectLock* frame::interpreter_frame_monitor_end() const { | |
285 return (BasicObjectLock*) get_interpreterState()->stack_base(); | |
286 } | |
287 | |
288 #else // CC_INTERP | |
289 | |
290 intptr_t* frame::interpreter_frame_sender_sp() const { | |
291 assert(is_interpreted_frame(), "interpreted frame expected"); | |
292 return (intptr_t*) at(interpreter_frame_sender_sp_offset); | |
293 } | |
294 | |
295 void frame::set_interpreter_frame_sender_sp(intptr_t* sender_sp) { | |
296 assert(is_interpreted_frame(), "interpreted frame expected"); | |
297 ptr_at_put(interpreter_frame_sender_sp_offset, (intptr_t) sender_sp); | |
298 } | |
299 | |
300 | |
301 // monitor elements | |
302 | |
303 BasicObjectLock* frame::interpreter_frame_monitor_begin() const { | |
304 return (BasicObjectLock*) addr_at(interpreter_frame_monitor_block_bottom_offset); | |
305 } | |
306 | |
307 BasicObjectLock* frame::interpreter_frame_monitor_end() const { | |
308 BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset); | |
309 // make sure the pointer points inside the frame | |
1488
615a9d95d265
6946056: assert((intptr_t) sp()<=(intptr_t) result,"result must>=than stack pointer"), frame_x86.cpp:295
johnc
parents:
1204
diff
changeset
|
310 assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer"); |
615a9d95d265
6946056: assert((intptr_t) sp()<=(intptr_t) result,"result must>=than stack pointer"), frame_x86.cpp:295
johnc
parents:
1204
diff
changeset
|
311 assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer"); |
0 | 312 return result; |
313 } | |
314 | |
315 void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) { | |
316 *((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value; | |
317 } | |
318 | |
319 // Used by template based interpreter deoptimization | |
320 void frame::interpreter_frame_set_last_sp(intptr_t* sp) { | |
321 *((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp; | |
322 } | |
323 #endif // CC_INTERP | |
324 | |
325 frame frame::sender_for_entry_frame(RegisterMap* map) const { | |
326 assert(map != NULL, "map must be set"); | |
327 // Java frame called from C; skip all C frames and return top C | |
328 // frame of that chunk as the sender | |
329 JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); | |
330 assert(!entry_frame_is_first(), "next Java fp must be non zero"); | |
331 assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack"); | |
332 map->clear(); | |
333 assert(map->include_argument_oops(), "should be set by clear"); | |
334 if (jfa->last_Java_pc() != NULL ) { | |
335 frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc()); | |
336 return fr; | |
337 } | |
338 frame fr(jfa->last_Java_sp(), jfa->last_Java_fp()); | |
339 return fr; | |
340 } | |
341 | |
1204 | 342 |
343 //------------------------------------------------------------------------------ | |
344 // frame::verify_deopt_original_pc | |
345 // | |
346 // Verifies the calculated original PC of a deoptimization PC for the | |
347 // given unextended SP. The unextended SP might also be the saved SP | |
348 // for MethodHandle call sites. | |
349 #if ASSERT | |
350 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) { | |
351 frame fr; | |
352 | |
353 // This is ugly but it's better than to change {get,set}_original_pc | |
354 // to take an SP value as argument. And it's only a debugging | |
355 // method anyway. | |
356 fr._unextended_sp = unextended_sp; | |
357 | |
358 address original_pc = nm->get_original_pc(&fr); | |
1748 | 359 assert(nm->insts_contains(original_pc), "original PC must be in nmethod"); |
1204 | 360 assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be"); |
361 } | |
362 #endif | |
363 | |
364 | |
365 //------------------------------------------------------------------------------ | |
366 // frame::sender_for_interpreter_frame | |
0 | 367 frame frame::sender_for_interpreter_frame(RegisterMap* map) const { |
1204 | 368 // SP is the raw SP from the sender after adapter or interpreter |
369 // extension. | |
370 intptr_t* sender_sp = this->sender_sp(); | |
0 | 371 |
372 // This is the sp before any possible extension (adapter/locals). | |
373 intptr_t* unextended_sp = interpreter_frame_sender_sp(); | |
374 | |
1204 | 375 // Stored FP. |
376 intptr_t* saved_fp = link(); | |
377 | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
378 address sender_pc = this->sender_pc(); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
379 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
380 assert(sender_cb, "sanity"); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
381 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); |
1204 | 382 |
383 if (sender_nm != NULL) { | |
384 // If the sender PC is a deoptimization point, get the original | |
385 // PC. For MethodHandle call site the unextended_sp is stored in | |
386 // saved_fp. | |
387 if (sender_nm->is_deopt_mh_entry(sender_pc)) { | |
388 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); | |
389 unextended_sp = saved_fp; | |
390 } | |
391 else if (sender_nm->is_deopt_entry(sender_pc)) { | |
392 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); | |
393 } | |
394 else if (sender_nm->is_method_handle_return(sender_pc)) { | |
395 unextended_sp = saved_fp; | |
396 } | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
397 } |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
398 |
0 | 399 // The interpreter and compiler(s) always save EBP/RBP in a known |
400 // location on entry. We must record where that location is | |
401 // so this if EBP/RBP was live on callout from c2 we can find | |
402 // the saved copy no matter what it called. | |
403 | |
404 // Since the interpreter always saves EBP/RBP if we record where it is then | |
405 // we don't have to always save EBP/RBP on entry and exit to c2 compiled | |
406 // code, on entry will be enough. | |
407 #ifdef COMPILER2 | |
408 if (map->update_map()) { | |
409 map->set_location(rbp->as_VMReg(), (address) addr_at(link_offset)); | |
410 #ifdef AMD64 | |
411 // this is weird "H" ought to be at a higher address however the | |
412 // oopMaps seems to have the "H" regs at the same address and the | |
413 // vanilla register. | |
414 // XXXX make this go away | |
415 if (true) { | |
416 map->set_location(rbp->as_VMReg()->next(), (address)addr_at(link_offset)); | |
417 } | |
418 #endif // AMD64 | |
419 } | |
1204 | 420 #endif // COMPILER2 |
421 | |
422 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); | |
0 | 423 } |
424 | |
425 | |
1204 | 426 //------------------------------------------------------------------------------ |
427 // frame::sender_for_compiled_frame | |
0 | 428 frame frame::sender_for_compiled_frame(RegisterMap* map) const { |
429 assert(map != NULL, "map must be set"); | |
430 | |
431 // frame owned by optimizing compiler | |
432 assert(_cb->frame_size() >= 0, "must have non-zero frame size"); | |
1204 | 433 intptr_t* sender_sp = unextended_sp() + _cb->frame_size(); |
434 intptr_t* unextended_sp = sender_sp; | |
0 | 435 |
436 // On Intel the return_address is always the word on the stack | |
437 address sender_pc = (address) *(sender_sp-1); | |
438 | |
1204 | 439 // This is the saved value of EBP which may or may not really be an FP. |
440 // It is only an FP if the sender is an interpreter frame (or C1?). | |
441 intptr_t* saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset); | |
0 | 442 |
1204 | 443 // If we are returning to a compiled MethodHandle call site, the |
444 // saved_fp will in fact be a saved value of the unextended SP. The | |
445 // simplest way to tell whether we are returning to such a call site | |
446 // is as follows: | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
447 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
448 assert(sender_cb, "sanity"); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
449 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); |
1204 | 450 |
451 if (sender_nm != NULL) { | |
452 // If the sender PC is a deoptimization point, get the original | |
453 // PC. For MethodHandle call site the unextended_sp is stored in | |
454 // saved_fp. | |
455 if (sender_nm->is_deopt_mh_entry(sender_pc)) { | |
456 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); | |
457 unextended_sp = saved_fp; | |
458 } | |
459 else if (sender_nm->is_deopt_entry(sender_pc)) { | |
460 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); | |
461 } | |
462 else if (sender_nm->is_method_handle_return(sender_pc)) { | |
463 unextended_sp = saved_fp; | |
464 } | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
465 } |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
466 |
0 | 467 if (map->update_map()) { |
468 // Tell GC to use argument oopmaps for some runtime stubs that need it. | |
469 // For C1, the runtime stub might not have oop maps, so set this flag | |
470 // outside of update_register_map. | |
471 map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread())); | |
472 if (_cb->oop_maps() != NULL) { | |
473 OopMapSet::update_register_map(this, map); | |
474 } | |
1204 | 475 // Since the prolog does the save and restore of EBP there is no oopmap |
0 | 476 // for it so we must fill in its location as if there was an oopmap entry |
477 // since if our caller was compiled code there could be live jvm state in it. | |
478 map->set_location(rbp->as_VMReg(), (address) (sender_sp - frame::sender_sp_offset)); | |
479 #ifdef AMD64 | |
480 // this is weird "H" ought to be at a higher address however the | |
481 // oopMaps seems to have the "H" regs at the same address and the | |
482 // vanilla register. | |
483 // XXXX make this go away | |
484 if (true) { | |
485 map->set_location(rbp->as_VMReg()->next(), (address) (sender_sp - frame::sender_sp_offset)); | |
486 } | |
487 #endif // AMD64 | |
488 } | |
489 | |
490 assert(sender_sp != sp(), "must have changed"); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
491 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); |
0 | 492 } |
493 | |
1204 | 494 |
495 //------------------------------------------------------------------------------ | |
496 // frame::sender | |
0 | 497 frame frame::sender(RegisterMap* map) const { |
498 // Default is we done have to follow them. The sender_for_xxx will | |
499 // update it accordingly | |
500 map->set_include_argument_oops(false); | |
501 | |
502 if (is_entry_frame()) return sender_for_entry_frame(map); | |
503 if (is_interpreted_frame()) return sender_for_interpreter_frame(map); | |
504 assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); | |
505 | |
506 if (_cb != NULL) { | |
507 return sender_for_compiled_frame(map); | |
508 } | |
509 // Must be native-compiled frame, i.e. the marshaling code for native | |
510 // methods that exists in the core system. | |
511 return frame(sender_sp(), link(), sender_pc()); | |
512 } | |
513 | |
514 | |
515 bool frame::interpreter_frame_equals_unpacked_fp(intptr_t* fp) { | |
516 assert(is_interpreted_frame(), "must be interpreter frame"); | |
517 methodOop method = interpreter_frame_method(); | |
518 // When unpacking an optimized frame the frame pointer is | |
519 // adjusted with: | |
520 int diff = (method->max_locals() - method->size_of_parameters()) * | |
1506 | 521 Interpreter::stackElementWords; |
0 | 522 return _fp == (fp - diff); |
523 } | |
524 | |
525 void frame::pd_gc_epilog() { | |
526 // nothing done here now | |
527 } | |
528 | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
529 bool frame::is_interpreted_frame_valid(JavaThread* thread) const { |
0 | 530 // QQQ |
531 #ifdef CC_INTERP | |
532 #else | |
533 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
534 // These are reasonable sanity checks | |
535 if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) { | |
536 return false; | |
537 } | |
538 if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { | |
539 return false; | |
540 } | |
541 if (fp() + interpreter_frame_initial_sp_offset < sp()) { | |
542 return false; | |
543 } | |
544 // These are hacks to keep us out of trouble. | |
545 // The problem with these is that they mask other problems | |
546 if (fp() <= sp()) { // this attempts to deal with unsigned comparison above | |
547 return false; | |
548 } | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
549 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
550 // do some validation of frame elements |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
551 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
552 // first the method |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
553 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
554 methodOop m = *interpreter_frame_method_addr(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
555 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
556 // validate the method we'd find in this potential sender |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
557 if (!Universe::heap()->is_valid_method(m)) return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
558 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
559 // stack frames shouldn't be much larger than max_stack elements |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
560 |
1506 | 561 if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { |
0 | 562 return false; |
563 } | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
564 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
565 // validate bci/bcx |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
566 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
567 intptr_t bcx = interpreter_frame_bcx(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
568 if (m->validate_bci_from_bcx(bcx) < 0) { |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
569 return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
570 } |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
571 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
572 // validate constantPoolCacheOop |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
573 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
574 constantPoolCacheOop cp = *interpreter_frame_cache_addr(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
575 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
576 if (cp == NULL || |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
577 !Space::is_aligned(cp) || |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
578 !Universe::heap()->is_permanent((void*)cp)) return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
579 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
580 // validate locals |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
581 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
582 address locals = (address) *interpreter_frame_locals_addr(); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
583 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
584 if (locals > thread->stack_base() || locals < (address) fp()) return false; |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
585 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
586 // We'd have to be pretty unlucky to be mislead at this point |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
587 |
0 | 588 #endif // CC_INTERP |
589 return true; | |
590 } | |
591 | |
592 BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { | |
593 #ifdef CC_INTERP | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
594 // Needed for JVMTI. The result should always be in the |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
595 // interpreterState object |
0 | 596 interpreterState istate = get_interpreterState(); |
597 #endif // CC_INTERP | |
598 assert(is_interpreted_frame(), "interpreted frame expected"); | |
599 methodOop method = interpreter_frame_method(); | |
600 BasicType type = method->result_type(); | |
601 | |
602 intptr_t* tos_addr; | |
603 if (method->is_native()) { | |
604 // Prior to calling into the runtime to report the method_exit the possible | |
605 // return value is pushed to the native stack. If the result is a jfloat/jdouble | |
606 // then ST0 is saved before EAX/EDX. See the note in generate_native_result | |
607 tos_addr = (intptr_t*)sp(); | |
608 if (type == T_FLOAT || type == T_DOUBLE) { | |
609 // QQQ seems like this code is equivalent on the two platforms | |
610 #ifdef AMD64 | |
611 // This is times two because we do a push(ltos) after pushing XMM0 | |
612 // and that takes two interpreter stack slots. | |
1506 | 613 tos_addr += 2 * Interpreter::stackElementWords; |
0 | 614 #else |
615 tos_addr += 2; | |
616 #endif // AMD64 | |
617 } | |
618 } else { | |
619 tos_addr = (intptr_t*)interpreter_frame_tos_address(); | |
620 } | |
621 | |
622 switch (type) { | |
623 case T_OBJECT : | |
624 case T_ARRAY : { | |
625 oop obj; | |
626 if (method->is_native()) { | |
627 #ifdef CC_INTERP | |
628 obj = istate->_oop_temp; | |
629 #else | |
630 obj = (oop) at(interpreter_frame_oop_temp_offset); | |
631 #endif // CC_INTERP | |
632 } else { | |
633 oop* obj_p = (oop*)tos_addr; | |
634 obj = (obj_p == NULL) ? (oop)NULL : *obj_p; | |
635 } | |
636 assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); | |
637 *oop_result = obj; | |
638 break; | |
639 } | |
640 case T_BOOLEAN : value_result->z = *(jboolean*)tos_addr; break; | |
641 case T_BYTE : value_result->b = *(jbyte*)tos_addr; break; | |
642 case T_CHAR : value_result->c = *(jchar*)tos_addr; break; | |
643 case T_SHORT : value_result->s = *(jshort*)tos_addr; break; | |
644 case T_INT : value_result->i = *(jint*)tos_addr; break; | |
645 case T_LONG : value_result->j = *(jlong*)tos_addr; break; | |
646 case T_FLOAT : { | |
647 #ifdef AMD64 | |
648 value_result->f = *(jfloat*)tos_addr; | |
649 #else | |
650 if (method->is_native()) { | |
651 jdouble d = *(jdouble*)tos_addr; // Result was in ST0 so need to convert to jfloat | |
652 value_result->f = (jfloat)d; | |
653 } else { | |
654 value_result->f = *(jfloat*)tos_addr; | |
655 } | |
656 #endif // AMD64 | |
657 break; | |
658 } | |
659 case T_DOUBLE : value_result->d = *(jdouble*)tos_addr; break; | |
660 case T_VOID : /* Nothing to do */ break; | |
661 default : ShouldNotReachHere(); | |
662 } | |
663 | |
664 return type; | |
665 } | |
666 | |
667 | |
668 intptr_t* frame::interpreter_frame_tos_at(jint offset) const { | |
669 int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize); | |
670 return &interpreter_frame_tos_address()[index]; | |
671 } |