Mercurial > hg > truffle
annotate src/cpu/x86/vm/frame_x86.inline.hpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 55fb97c4c58d |
children | 78112be27ba0 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
11146
diff
changeset
|
2 * Copyright (c) 1997, 2013, 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:
1255
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1255
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:
1255
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef CPU_X86_VM_FRAME_X86_INLINE_HPP |
26 #define CPU_X86_VM_FRAME_X86_INLINE_HPP | |
27 | |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
6725
diff
changeset
|
28 #include "code/codeCache.hpp" |
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
6725
diff
changeset
|
29 |
0 | 30 // Inline functions for Intel frames: |
31 | |
32 // Constructors: | |
33 | |
34 inline frame::frame() { | |
35 _pc = NULL; | |
36 _sp = NULL; | |
37 _unextended_sp = NULL; | |
38 _fp = NULL; | |
39 _cb = NULL; | |
40 _deopt_state = unknown; | |
41 } | |
42 | |
1204 | 43 inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) { |
0 | 44 _sp = sp; |
45 _unextended_sp = sp; | |
46 _fp = fp; | |
47 _pc = pc; | |
48 assert(pc != NULL, "no pc?"); | |
49 _cb = CodeCache::find_blob(pc); | |
3755
5cf771a79037
7047697: MethodHandle.invokeExact call for wrong method causes VM failure if run with -Xcomp
jrose
parents:
3363
diff
changeset
|
50 adjust_unextended_sp(); |
1204 | 51 |
52 address original_pc = nmethod::get_deopt_original_pc(this); | |
53 if (original_pc != NULL) { | |
54 _pc = original_pc; | |
0 | 55 _deopt_state = is_deoptimized; |
56 } else { | |
57 _deopt_state = not_deoptimized; | |
58 } | |
59 } | |
60 | |
1204 | 61 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) { |
0 | 62 _sp = sp; |
63 _unextended_sp = unextended_sp; | |
64 _fp = fp; | |
65 _pc = pc; | |
66 assert(pc != NULL, "no pc?"); | |
67 _cb = CodeCache::find_blob(pc); | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
1972
diff
changeset
|
68 adjust_unextended_sp(); |
1204 | 69 |
70 address original_pc = nmethod::get_deopt_original_pc(this); | |
71 if (original_pc != NULL) { | |
72 _pc = original_pc; | |
1748 | 73 assert(((nmethod*)_cb)->insts_contains(_pc), "original PC must be in nmethod"); |
0 | 74 _deopt_state = is_deoptimized; |
75 } else { | |
76 _deopt_state = not_deoptimized; | |
77 } | |
78 } | |
79 | |
80 inline frame::frame(intptr_t* sp, intptr_t* fp) { | |
81 _sp = sp; | |
82 _unextended_sp = sp; | |
83 _fp = fp; | |
84 _pc = (address)(sp[-1]); | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
85 |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
86 // Here's a sticky one. This constructor can be called via AsyncGetCallTrace |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
87 // when last_Java_sp is non-null but the pc fetched is junk. If we are truly |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
88 // unlucky the junk value could be to a zombied method and we'll die on the |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
89 // find_blob call. This is also why we can have no asserts on the validity |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
90 // of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
91 // -> pd_last_frame should use a specialized version of pd_last_frame which could |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
92 // call a specilaized frame constructor instead of this one. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
93 // Then we could use the assert below. However this assert is of somewhat dubious |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
94 // value. |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
95 // assert(_pc != NULL, "no pc?"); |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
96 |
0 | 97 _cb = CodeCache::find_blob(_pc); |
3755
5cf771a79037
7047697: MethodHandle.invokeExact call for wrong method causes VM failure if run with -Xcomp
jrose
parents:
3363
diff
changeset
|
98 adjust_unextended_sp(); |
0 | 99 |
1204 | 100 address original_pc = nmethod::get_deopt_original_pc(this); |
101 if (original_pc != NULL) { | |
102 _pc = original_pc; | |
0 | 103 _deopt_state = is_deoptimized; |
104 } else { | |
105 _deopt_state = not_deoptimized; | |
106 } | |
107 } | |
108 | |
109 // Accessors | |
110 | |
111 inline bool frame::equal(frame other) const { | |
112 bool ret = sp() == other.sp() | |
113 && unextended_sp() == other.unextended_sp() | |
114 && fp() == other.fp() | |
115 && pc() == other.pc(); | |
116 assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction"); | |
117 return ret; | |
118 } | |
119 | |
120 // Return unique id for this frame. The id must have a value where we can distinguish | |
121 // identity and younger/older relationship. NULL represents an invalid (incomparable) | |
122 // frame. | |
123 inline intptr_t* frame::id(void) const { return unextended_sp(); } | |
124 | |
125 // Relationals on frames based | |
126 // Return true if the frame is younger (more recent activation) than the frame represented by id | |
127 inline bool frame::is_younger(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id"); | |
128 return this->id() < id ; } | |
129 | |
130 // Return true if the frame is older (less recent activation) than the frame represented by id | |
131 inline bool frame::is_older(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id"); | |
132 return this->id() > id ; } | |
133 | |
134 | |
135 | |
136 inline intptr_t* frame::link() const { return (intptr_t*) *(intptr_t **)addr_at(link_offset); } | |
137 inline void frame::set_link(intptr_t* addr) { *(intptr_t **)addr_at(link_offset) = addr; } | |
138 | |
139 | |
140 inline intptr_t* frame::unextended_sp() const { return _unextended_sp; } | |
141 | |
142 // Return address: | |
143 | |
144 inline address* frame::sender_pc_addr() const { return (address*) addr_at( return_addr_offset); } | |
145 inline address frame::sender_pc() const { return *sender_pc_addr(); } | |
146 | |
147 // return address of param, zero origin index. | |
148 inline address* frame::native_param_addr(int idx) const { return (address*) addr_at( native_frame_initial_param_offset+idx); } | |
149 | |
150 #ifdef CC_INTERP | |
151 | |
152 inline interpreterState frame::get_interpreterState() const { | |
520
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
304
diff
changeset
|
153 return ((interpreterState)addr_at( -((int)sizeof(BytecodeInterpreter))/wordSize )); |
0 | 154 } |
155 | |
156 inline intptr_t* frame::sender_sp() const { | |
157 // Hmm this seems awfully expensive QQQ, is this really called with interpreted frames? | |
158 if (is_interpreted_frame()) { | |
159 assert(false, "should never happen"); | |
160 return get_interpreterState()->sender_sp(); | |
161 } else { | |
162 return addr_at(sender_sp_offset); | |
163 } | |
164 } | |
165 | |
166 inline intptr_t** frame::interpreter_frame_locals_addr() const { | |
167 assert(is_interpreted_frame(), "must be interpreted"); | |
168 return &(get_interpreterState()->_locals); | |
169 } | |
170 | |
171 inline intptr_t* frame::interpreter_frame_bcx_addr() const { | |
172 assert(is_interpreted_frame(), "must be interpreted"); | |
304 | 173 return (intptr_t*) &(get_interpreterState()->_bcp); |
0 | 174 } |
175 | |
176 | |
177 // Constant pool cache | |
178 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3755
diff
changeset
|
179 inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const { |
0 | 180 assert(is_interpreted_frame(), "must be interpreted"); |
181 return &(get_interpreterState()->_constants); | |
182 } | |
183 | |
184 // Method | |
185 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3755
diff
changeset
|
186 inline Method** frame::interpreter_frame_method_addr() const { |
0 | 187 assert(is_interpreted_frame(), "must be interpreted"); |
188 return &(get_interpreterState()->_method); | |
189 } | |
190 | |
191 inline intptr_t* frame::interpreter_frame_mdx_addr() const { | |
192 assert(is_interpreted_frame(), "must be interpreted"); | |
304 | 193 return (intptr_t*) &(get_interpreterState()->_mdx); |
0 | 194 } |
195 | |
196 // top of expression stack | |
197 inline intptr_t* frame::interpreter_frame_tos_address() const { | |
198 assert(is_interpreted_frame(), "wrong frame type"); | |
199 return get_interpreterState()->_stack + 1; | |
200 } | |
201 | |
202 #else /* asm interpreter */ | |
203 inline intptr_t* frame::sender_sp() const { return addr_at( sender_sp_offset); } | |
204 | |
205 inline intptr_t** frame::interpreter_frame_locals_addr() const { | |
206 return (intptr_t**)addr_at(interpreter_frame_locals_offset); | |
207 } | |
208 | |
209 inline intptr_t* frame::interpreter_frame_last_sp() const { | |
210 return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset); | |
211 } | |
212 | |
213 inline intptr_t* frame::interpreter_frame_bcx_addr() const { | |
214 return (intptr_t*)addr_at(interpreter_frame_bcx_offset); | |
215 } | |
216 | |
217 | |
218 inline intptr_t* frame::interpreter_frame_mdx_addr() const { | |
219 return (intptr_t*)addr_at(interpreter_frame_mdx_offset); | |
220 } | |
221 | |
222 | |
223 | |
224 // Constant pool cache | |
225 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3755
diff
changeset
|
226 inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3755
diff
changeset
|
227 return (ConstantPoolCache**)addr_at(interpreter_frame_cache_offset); |
0 | 228 } |
229 | |
230 // Method | |
231 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3755
diff
changeset
|
232 inline Method** frame::interpreter_frame_method_addr() const { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3755
diff
changeset
|
233 return (Method**)addr_at(interpreter_frame_method_offset); |
0 | 234 } |
235 | |
236 // top of expression stack | |
237 inline intptr_t* frame::interpreter_frame_tos_address() const { | |
238 intptr_t* last_sp = interpreter_frame_last_sp(); | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
579
diff
changeset
|
239 if (last_sp == NULL) { |
0 | 240 return sp(); |
241 } else { | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
579
diff
changeset
|
242 // sp() may have been extended or shrunk by an adapter. At least |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
579
diff
changeset
|
243 // check that we don't fall behind the legal region. |
1255
e3a4305c6bc3
6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents:
1204
diff
changeset
|
244 // For top deoptimized frame last_sp == interpreter_frame_monitor_end. |
e3a4305c6bc3
6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents:
1204
diff
changeset
|
245 assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos"); |
0 | 246 return last_sp; |
247 } | |
248 } | |
249 | |
250 #endif /* CC_INTERP */ | |
251 | |
252 inline int frame::pd_oop_map_offset_adjustment() const { | |
253 return 0; | |
254 } | |
255 | |
256 inline int frame::interpreter_frame_monitor_size() { | |
257 return BasicObjectLock::size(); | |
258 } | |
259 | |
260 | |
261 // expression stack | |
262 // (the max_stack arguments are used by the GC; see class FrameClosure) | |
263 | |
264 inline intptr_t* frame::interpreter_frame_expression_stack() const { | |
265 intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end(); | |
266 return monitor_end-1; | |
267 } | |
268 | |
269 | |
270 inline jint frame::interpreter_frame_expression_stack_direction() { return -1; } | |
271 | |
272 | |
273 // Entry frames | |
274 | |
11146
e619a2766bcc
8016131: nsk/sysdict/vm/stress/chain tests crash the VM in 'entry_frame_is_first()'
rbackman
parents:
8762
diff
changeset
|
275 inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { |
e619a2766bcc
8016131: nsk/sysdict/vm/stress/chain tests crash the VM in 'entry_frame_is_first()'
rbackman
parents:
8762
diff
changeset
|
276 return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset); |
0 | 277 } |
278 | |
279 // Compiled frames | |
280 | |
281 inline int frame::local_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors) { | |
282 return (nof_args - local_index + (local_index < nof_args ? 1: -1)); | |
283 } | |
284 | |
285 inline int frame::monitor_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors) { | |
286 return local_offset_for_compiler(local_index, nof_args, max_nof_locals, max_nof_monitors); | |
287 } | |
288 | |
289 inline int frame::min_local_offset_for_compiler(int nof_args, int max_nof_locals, int max_nof_monitors) { | |
290 return (nof_args - (max_nof_locals + max_nof_monitors*2) - 1); | |
291 } | |
292 | |
293 inline bool frame::volatile_across_calls(Register reg) { | |
294 return true; | |
295 } | |
296 | |
8762
0a2deac0bbfb
8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
morris
parents:
7199
diff
changeset
|
297 inline oop frame::saved_oop_result(RegisterMap* map) const { |
0a2deac0bbfb
8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
morris
parents:
7199
diff
changeset
|
298 oop* result_adr = (oop *)map->location(rax->as_VMReg()); |
0a2deac0bbfb
8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
morris
parents:
7199
diff
changeset
|
299 guarantee(result_adr != NULL, "bad register save location"); |
0 | 300 |
8762
0a2deac0bbfb
8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
morris
parents:
7199
diff
changeset
|
301 return (*result_adr); |
0 | 302 } |
303 | |
304 inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { | |
8762
0a2deac0bbfb
8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
morris
parents:
7199
diff
changeset
|
305 oop* result_adr = (oop *)map->location(rax->as_VMReg()); |
0a2deac0bbfb
8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
morris
parents:
7199
diff
changeset
|
306 guarantee(result_adr != NULL, "bad register save location"); |
0a2deac0bbfb
8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
morris
parents:
7199
diff
changeset
|
307 |
0a2deac0bbfb
8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
morris
parents:
7199
diff
changeset
|
308 *result_adr = obj; |
0 | 309 } |
1972 | 310 |
311 #endif // CPU_X86_VM_FRAME_X86_INLINE_HPP |