Mercurial > hg > truffle
annotate src/cpu/x86/vm/frame_x86.cpp @ 4582:b24386206122
Made all vm builds go into subdirectories, even product builds to simplify building the various types of VMs (server, client and graal).
Made HotSpot build jobs use the number of CPUs on the host machine.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 13 Feb 2012 23:13:37 +0100 |
parents | 04b9a2566eec |
children | 3dbcd1013cc8 |
rev | line source |
---|---|
0 | 1 /* |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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) { | |
4000
0abefdb54d21
7081938: JSR292: assert(magic_number_2() == MAGIC_NUMBER_2) failed
twisti
parents:
3931
diff
changeset
|
235 address* pc_addr = &(((address*) sp())[-1]); |
0 | 236 if (TracePcPatching) { |
4056
448691f285a5
7106944: assert(_pc == *pc_addr) failed may be too strong
twisti
parents:
4000
diff
changeset
|
237 tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]", |
4000
0abefdb54d21
7081938: JSR292: assert(magic_number_2() == MAGIC_NUMBER_2) failed
twisti
parents:
3931
diff
changeset
|
238 pc_addr, *pc_addr, pc); |
0 | 239 } |
4056
448691f285a5
7106944: assert(_pc == *pc_addr) failed may be too strong
twisti
parents:
4000
diff
changeset
|
240 // Either the return address is the original one or we are going to |
448691f285a5
7106944: assert(_pc == *pc_addr) failed may be too strong
twisti
parents:
4000
diff
changeset
|
241 // patch in the same address that's already there. |
448691f285a5
7106944: assert(_pc == *pc_addr) failed may be too strong
twisti
parents:
4000
diff
changeset
|
242 assert(_pc == *pc_addr || pc == *pc_addr, "must be"); |
4000
0abefdb54d21
7081938: JSR292: assert(magic_number_2() == MAGIC_NUMBER_2) failed
twisti
parents:
3931
diff
changeset
|
243 *pc_addr = pc; |
0 | 244 _cb = CodeCache::find_blob(pc); |
1204 | 245 address original_pc = nmethod::get_deopt_original_pc(this); |
246 if (original_pc != NULL) { | |
247 assert(original_pc == _pc, "expected original PC to be stored before patching"); | |
0 | 248 _deopt_state = is_deoptimized; |
249 // leave _pc as is | |
250 } else { | |
251 _deopt_state = not_deoptimized; | |
252 _pc = pc; | |
253 } | |
254 } | |
255 | |
256 bool frame::is_interpreted_frame() const { | |
257 return Interpreter::contains(pc()); | |
258 } | |
259 | |
793
eacd97c88873
6848466: frame::frame_size() assertion failure with -XX:+DebugDeoptimization
cfang
parents:
304
diff
changeset
|
260 int frame::frame_size(RegisterMap* map) const { |
eacd97c88873
6848466: frame::frame_size() assertion failure with -XX:+DebugDeoptimization
cfang
parents:
304
diff
changeset
|
261 frame sender = this->sender(map); |
0 | 262 return sender.sp() - sp(); |
263 } | |
264 | |
265 intptr_t* frame::entry_frame_argument_at(int offset) const { | |
266 // convert offset to index to deal with tsi | |
267 int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize); | |
268 // Entry frame's arguments are always in relation to unextended_sp() | |
269 return &unextended_sp()[index]; | |
270 } | |
271 | |
272 // sender_sp | |
273 #ifdef CC_INTERP | |
274 intptr_t* frame::interpreter_frame_sender_sp() const { | |
275 assert(is_interpreted_frame(), "interpreted frame expected"); | |
276 // QQQ why does this specialize method exist if frame::sender_sp() does same thing? | |
277 // seems odd and if we always know interpreted vs. non then sender_sp() is really | |
278 // doing too much work. | |
279 return get_interpreterState()->sender_sp(); | |
280 } | |
281 | |
282 // monitor elements | |
283 | |
284 BasicObjectLock* frame::interpreter_frame_monitor_begin() const { | |
285 return get_interpreterState()->monitor_base(); | |
286 } | |
287 | |
288 BasicObjectLock* frame::interpreter_frame_monitor_end() const { | |
289 return (BasicObjectLock*) get_interpreterState()->stack_base(); | |
290 } | |
291 | |
292 #else // CC_INTERP | |
293 | |
294 intptr_t* frame::interpreter_frame_sender_sp() const { | |
295 assert(is_interpreted_frame(), "interpreted frame expected"); | |
296 return (intptr_t*) at(interpreter_frame_sender_sp_offset); | |
297 } | |
298 | |
299 void frame::set_interpreter_frame_sender_sp(intptr_t* sender_sp) { | |
300 assert(is_interpreted_frame(), "interpreted frame expected"); | |
301 ptr_at_put(interpreter_frame_sender_sp_offset, (intptr_t) sender_sp); | |
302 } | |
303 | |
304 | |
305 // monitor elements | |
306 | |
307 BasicObjectLock* frame::interpreter_frame_monitor_begin() const { | |
308 return (BasicObjectLock*) addr_at(interpreter_frame_monitor_block_bottom_offset); | |
309 } | |
310 | |
311 BasicObjectLock* frame::interpreter_frame_monitor_end() const { | |
312 BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset); | |
313 // 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
|
314 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
|
315 assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer"); |
0 | 316 return result; |
317 } | |
318 | |
319 void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) { | |
320 *((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value; | |
321 } | |
322 | |
323 // Used by template based interpreter deoptimization | |
324 void frame::interpreter_frame_set_last_sp(intptr_t* sp) { | |
325 *((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp; | |
326 } | |
327 #endif // CC_INTERP | |
328 | |
329 frame frame::sender_for_entry_frame(RegisterMap* map) const { | |
330 assert(map != NULL, "map must be set"); | |
331 // Java frame called from C; skip all C frames and return top C | |
332 // frame of that chunk as the sender | |
333 JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); | |
334 assert(!entry_frame_is_first(), "next Java fp must be non zero"); | |
335 assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack"); | |
336 map->clear(); | |
337 assert(map->include_argument_oops(), "should be set by clear"); | |
338 if (jfa->last_Java_pc() != NULL ) { | |
339 frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc()); | |
340 return fr; | |
341 } | |
342 frame fr(jfa->last_Java_sp(), jfa->last_Java_fp()); | |
343 return fr; | |
344 } | |
345 | |
1204 | 346 //------------------------------------------------------------------------------ |
347 // frame::verify_deopt_original_pc | |
348 // | |
349 // Verifies the calculated original PC of a deoptimization PC for the | |
350 // given unextended SP. The unextended SP might also be the saved SP | |
351 // for MethodHandle call sites. | |
352 #if ASSERT | |
353 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) { | |
354 frame fr; | |
355 | |
356 // This is ugly but it's better than to change {get,set}_original_pc | |
357 // to take an SP value as argument. And it's only a debugging | |
358 // method anyway. | |
359 fr._unextended_sp = unextended_sp; | |
360 | |
361 address original_pc = nm->get_original_pc(&fr); | |
1748 | 362 assert(nm->insts_contains(original_pc), "original PC must be in nmethod"); |
1204 | 363 assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be"); |
364 } | |
365 #endif | |
366 | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
367 //------------------------------------------------------------------------------ |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
368 // frame::adjust_unextended_sp |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
369 void frame::adjust_unextended_sp() { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
370 // If we are returning to a compiled MethodHandle call site, the |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
371 // saved_fp will in fact be a saved value of the unextended SP. The |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
372 // simplest way to tell whether we are returning to such a call site |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
373 // is as follows: |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
374 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
375 nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null(); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
376 if (sender_nm != NULL) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
377 // If the sender PC is a deoptimization point, get the original |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
378 // PC. For MethodHandle call site the unextended_sp is stored in |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
379 // saved_fp. |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
380 if (sender_nm->is_deopt_mh_entry(_pc)) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
381 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, _fp)); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
382 _unextended_sp = _fp; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
383 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
384 else if (sender_nm->is_deopt_entry(_pc)) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
385 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp)); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
386 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
387 else if (sender_nm->is_method_handle_return(_pc)) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
388 _unextended_sp = _fp; |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
389 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
390 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
391 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
392 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
393 //------------------------------------------------------------------------------ |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
394 // frame::update_map_with_saved_link |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
395 void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
396 // The interpreter and compiler(s) always save EBP/RBP in a known |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
397 // location on entry. We must record where that location is |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
398 // so this if EBP/RBP was live on callout from c2 we can find |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
399 // the saved copy no matter what it called. |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
400 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
401 // Since the interpreter always saves EBP/RBP if we record where it is then |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
402 // we don't have to always save EBP/RBP on entry and exit to c2 compiled |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
403 // code, on entry will be enough. |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
404 map->set_location(rbp->as_VMReg(), (address) link_addr); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
405 #ifdef AMD64 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
406 // this is weird "H" ought to be at a higher address however the |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
407 // oopMaps seems to have the "H" regs at the same address and the |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
408 // vanilla register. |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
409 // XXXX make this go away |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
410 if (true) { |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
411 map->set_location(rbp->as_VMReg()->next(), (address) link_addr); |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
412 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
413 #endif // AMD64 |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
414 } |
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
415 |
1204 | 416 |
417 //------------------------------------------------------------------------------ | |
418 // frame::sender_for_interpreter_frame | |
0 | 419 frame frame::sender_for_interpreter_frame(RegisterMap* map) const { |
1204 | 420 // SP is the raw SP from the sender after adapter or interpreter |
421 // extension. | |
422 intptr_t* sender_sp = this->sender_sp(); | |
0 | 423 |
424 // This is the sp before any possible extension (adapter/locals). | |
425 intptr_t* unextended_sp = interpreter_frame_sender_sp(); | |
426 | |
427 #ifdef COMPILER2 | |
428 if (map->update_map()) { | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
429 update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); |
0 | 430 } |
1204 | 431 #endif // COMPILER2 |
432 | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
433 return frame(sender_sp, unextended_sp, link(), sender_pc()); |
0 | 434 } |
435 | |
436 | |
1204 | 437 //------------------------------------------------------------------------------ |
438 // frame::sender_for_compiled_frame | |
0 | 439 frame frame::sender_for_compiled_frame(RegisterMap* map) const { |
440 assert(map != NULL, "map must be set"); | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
441 assert(!is_ricochet_frame(), "caller must handle this"); |
0 | 442 |
443 // frame owned by optimizing compiler | |
444 assert(_cb->frame_size() >= 0, "must have non-zero frame size"); | |
1204 | 445 intptr_t* sender_sp = unextended_sp() + _cb->frame_size(); |
446 intptr_t* unextended_sp = sender_sp; | |
0 | 447 |
448 // On Intel the return_address is always the word on the stack | |
449 address sender_pc = (address) *(sender_sp-1); | |
450 | |
1204 | 451 // This is the saved value of EBP which may or may not really be an FP. |
452 // It is only an FP if the sender is an interpreter frame (or C1?). | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
453 intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
454 |
0 | 455 if (map->update_map()) { |
456 // Tell GC to use argument oopmaps for some runtime stubs that need it. | |
457 // For C1, the runtime stub might not have oop maps, so set this flag | |
458 // outside of update_register_map. | |
459 map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread())); | |
460 if (_cb->oop_maps() != NULL) { | |
461 OopMapSet::update_register_map(this, map); | |
462 } | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
463 |
1204 | 464 // Since the prolog does the save and restore of EBP there is no oopmap |
0 | 465 // for it so we must fill in its location as if there was an oopmap entry |
466 // since if our caller was compiled code there could be live jvm state in it. | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
467 update_map_with_saved_link(map, saved_fp_addr); |
0 | 468 } |
469 | |
470 assert(sender_sp != sp(), "must have changed"); | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
471 return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc); |
0 | 472 } |
473 | |
1204 | 474 |
475 //------------------------------------------------------------------------------ | |
476 // frame::sender | |
0 | 477 frame frame::sender(RegisterMap* map) const { |
478 // Default is we done have to follow them. The sender_for_xxx will | |
479 // update it accordingly | |
480 map->set_include_argument_oops(false); | |
481 | |
482 if (is_entry_frame()) return sender_for_entry_frame(map); | |
483 if (is_interpreted_frame()) return sender_for_interpreter_frame(map); | |
484 assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
485 if (is_ricochet_frame()) return sender_for_ricochet_frame(map); |
0 | 486 |
487 if (_cb != NULL) { | |
488 return sender_for_compiled_frame(map); | |
489 } | |
490 // Must be native-compiled frame, i.e. the marshaling code for native | |
491 // methods that exists in the core system. | |
492 return frame(sender_sp(), link(), sender_pc()); | |
493 } | |
494 | |
495 | |
496 bool frame::interpreter_frame_equals_unpacked_fp(intptr_t* fp) { | |
497 assert(is_interpreted_frame(), "must be interpreter frame"); | |
498 methodOop method = interpreter_frame_method(); | |
499 // When unpacking an optimized frame the frame pointer is | |
500 // adjusted with: | |
501 int diff = (method->max_locals() - method->size_of_parameters()) * | |
1506 | 502 Interpreter::stackElementWords; |
0 | 503 return _fp == (fp - diff); |
504 } | |
505 | |
506 void frame::pd_gc_epilog() { | |
507 // nothing done here now | |
508 } | |
509 | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
510 bool frame::is_interpreted_frame_valid(JavaThread* thread) const { |
0 | 511 // QQQ |
512 #ifdef CC_INTERP | |
513 #else | |
514 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
515 // These are reasonable sanity checks | |
516 if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) { | |
517 return false; | |
518 } | |
519 if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { | |
520 return false; | |
521 } | |
522 if (fp() + interpreter_frame_initial_sp_offset < sp()) { | |
523 return false; | |
524 } | |
525 // These are hacks to keep us out of trouble. | |
526 // The problem with these is that they mask other problems | |
527 if (fp() <= sp()) { // this attempts to deal with unsigned comparison above | |
528 return false; | |
529 } | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
530 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
531 // 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
|
532 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
533 // first the method |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
534 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
535 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
|
536 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
537 // 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
|
538 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
|
539 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
540 // 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
|
541 |
1506 | 542 if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { |
0 | 543 return false; |
544 } | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
545 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
546 // validate bci/bcx |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
547 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
548 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
|
549 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
|
550 return false; |
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 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
553 // validate constantPoolCacheOop |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
554 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
555 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
|
556 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
557 if (cp == NULL || |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
558 !Space::is_aligned(cp) || |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
559 !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
|
560 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
561 // validate locals |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
562 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
563 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
|
564 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
565 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
|
566 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
567 // 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
|
568 |
0 | 569 #endif // CC_INTERP |
570 return true; | |
571 } | |
572 | |
573 BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { | |
574 #ifdef CC_INTERP | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
575 // Needed for JVMTI. The result should always be in the |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
576 // interpreterState object |
0 | 577 interpreterState istate = get_interpreterState(); |
578 #endif // CC_INTERP | |
579 assert(is_interpreted_frame(), "interpreted frame expected"); | |
580 methodOop method = interpreter_frame_method(); | |
581 BasicType type = method->result_type(); | |
582 | |
583 intptr_t* tos_addr; | |
584 if (method->is_native()) { | |
585 // Prior to calling into the runtime to report the method_exit the possible | |
586 // return value is pushed to the native stack. If the result is a jfloat/jdouble | |
587 // then ST0 is saved before EAX/EDX. See the note in generate_native_result | |
588 tos_addr = (intptr_t*)sp(); | |
589 if (type == T_FLOAT || type == T_DOUBLE) { | |
590 // QQQ seems like this code is equivalent on the two platforms | |
591 #ifdef AMD64 | |
592 // This is times two because we do a push(ltos) after pushing XMM0 | |
593 // and that takes two interpreter stack slots. | |
1506 | 594 tos_addr += 2 * Interpreter::stackElementWords; |
0 | 595 #else |
596 tos_addr += 2; | |
597 #endif // AMD64 | |
598 } | |
599 } else { | |
600 tos_addr = (intptr_t*)interpreter_frame_tos_address(); | |
601 } | |
602 | |
603 switch (type) { | |
604 case T_OBJECT : | |
605 case T_ARRAY : { | |
606 oop obj; | |
607 if (method->is_native()) { | |
608 #ifdef CC_INTERP | |
609 obj = istate->_oop_temp; | |
610 #else | |
611 obj = (oop) at(interpreter_frame_oop_temp_offset); | |
612 #endif // CC_INTERP | |
613 } else { | |
614 oop* obj_p = (oop*)tos_addr; | |
615 obj = (obj_p == NULL) ? (oop)NULL : *obj_p; | |
616 } | |
617 assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); | |
618 *oop_result = obj; | |
619 break; | |
620 } | |
621 case T_BOOLEAN : value_result->z = *(jboolean*)tos_addr; break; | |
622 case T_BYTE : value_result->b = *(jbyte*)tos_addr; break; | |
623 case T_CHAR : value_result->c = *(jchar*)tos_addr; break; | |
624 case T_SHORT : value_result->s = *(jshort*)tos_addr; break; | |
625 case T_INT : value_result->i = *(jint*)tos_addr; break; | |
626 case T_LONG : value_result->j = *(jlong*)tos_addr; break; | |
627 case T_FLOAT : { | |
628 #ifdef AMD64 | |
629 value_result->f = *(jfloat*)tos_addr; | |
630 #else | |
631 if (method->is_native()) { | |
632 jdouble d = *(jdouble*)tos_addr; // Result was in ST0 so need to convert to jfloat | |
633 value_result->f = (jfloat)d; | |
634 } else { | |
635 value_result->f = *(jfloat*)tos_addr; | |
636 } | |
637 #endif // AMD64 | |
638 break; | |
639 } | |
640 case T_DOUBLE : value_result->d = *(jdouble*)tos_addr; break; | |
641 case T_VOID : /* Nothing to do */ break; | |
642 default : ShouldNotReachHere(); | |
643 } | |
644 | |
645 return type; | |
646 } | |
647 | |
648 | |
649 intptr_t* frame::interpreter_frame_tos_at(jint offset) const { | |
650 int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize); | |
651 return &interpreter_frame_tos_address()[index]; | |
652 } | |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
653 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
654 #ifdef ASSERT |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
655 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
656 #define DESCRIBE_FP_OFFSET(name) \ |
3365
3cfb240033d1
7043301: assert(locals < caller->fp() || locals > (caller->fp() + 16)) failed: locals in save area
never
parents:
3363
diff
changeset
|
657 values.describe(frame_no, fp() + frame::name##_offset, #name) |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
658 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
659 void frame::describe_pd(FrameValues& values, int frame_no) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
660 if (is_interpreted_frame()) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
661 DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
662 DESCRIBE_FP_OFFSET(interpreter_frame_last_sp); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
663 DESCRIBE_FP_OFFSET(interpreter_frame_method); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
664 DESCRIBE_FP_OFFSET(interpreter_frame_mdx); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
665 DESCRIBE_FP_OFFSET(interpreter_frame_cache); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
666 DESCRIBE_FP_OFFSET(interpreter_frame_locals); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
667 DESCRIBE_FP_OFFSET(interpreter_frame_bcx); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
668 DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
669 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
670 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
671 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
1972
diff
changeset
|
672 #endif |
3931
5432047c7db7
7087445: Improve platform independence of JSR292 shared code
bdelsart
parents:
3365
diff
changeset
|
673 |
5432047c7db7
7087445: Improve platform independence of JSR292 shared code
bdelsart
parents:
3365
diff
changeset
|
674 intptr_t *frame::initial_deoptimization_info() { |
5432047c7db7
7087445: Improve platform independence of JSR292 shared code
bdelsart
parents:
3365
diff
changeset
|
675 // used to reset the saved FP |
5432047c7db7
7087445: Improve platform independence of JSR292 shared code
bdelsart
parents:
3365
diff
changeset
|
676 return fp(); |
5432047c7db7
7087445: Improve platform independence of JSR292 shared code
bdelsart
parents:
3365
diff
changeset
|
677 } |