Mercurial > hg > truffle
annotate src/share/vm/prims/jvmtiEnvThreadState.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 78bbf4d43a14 |
children | 52b4284cb496 |
rev | line source |
---|---|
0 | 1 /* |
17639
7b35e546ba31
8030027: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Linux-amd64: SIGSEGV in JavaThread::last_java_vframe(RegisterMap*)+0xfa
sspitsyn
parents:
17467
diff
changeset
|
2 * Copyright (c) 2003, 2014, 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:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
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:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "interpreter/interpreter.hpp" | |
28 #include "jvmtifiles/jvmtiEnv.hpp" | |
29 #include "memory/resourceArea.hpp" | |
30 #include "prims/jvmtiEnvThreadState.hpp" | |
31 #include "prims/jvmtiEventController.inline.hpp" | |
32 #include "prims/jvmtiImpl.hpp" | |
33 #include "runtime/handles.hpp" | |
34 #include "runtime/handles.inline.hpp" | |
35 #include "runtime/interfaceSupport.hpp" | |
36 #include "runtime/javaCalls.hpp" | |
37 #include "runtime/signature.hpp" | |
38 #include "runtime/vframe.hpp" | |
39 #include "runtime/vm_operations.hpp" | |
0 | 40 |
41 | |
42 /////////////////////////////////////////////////////////////// | |
43 // | |
44 // class JvmtiFramePop | |
45 // | |
46 | |
47 #ifndef PRODUCT | |
48 void JvmtiFramePop::print() { | |
49 tty->print_cr("_frame_number=%d", _frame_number); | |
50 } | |
51 #endif | |
52 | |
53 | |
54 /////////////////////////////////////////////////////////////// | |
55 // | |
56 // class JvmtiFramePops - private methods | |
57 // | |
58 | |
59 void | |
60 JvmtiFramePops::set(JvmtiFramePop& fp) { | |
61 if (_pops->find(fp.frame_number()) < 0) { | |
62 _pops->append(fp.frame_number()); | |
63 } | |
64 } | |
65 | |
66 | |
67 void | |
68 JvmtiFramePops::clear(JvmtiFramePop& fp) { | |
69 assert(_pops->length() > 0, "No more frame pops"); | |
70 | |
71 _pops->remove(fp.frame_number()); | |
72 } | |
73 | |
74 | |
75 int | |
76 JvmtiFramePops::clear_to(JvmtiFramePop& fp) { | |
77 int cleared = 0; | |
78 int index = 0; | |
79 while (index < _pops->length()) { | |
80 JvmtiFramePop pop = JvmtiFramePop(_pops->at(index)); | |
81 if (pop.above_on_stack(fp)) { | |
82 _pops->remove_at(index); | |
83 ++cleared; | |
84 } else { | |
85 ++index; | |
86 } | |
87 } | |
88 return cleared; | |
89 } | |
90 | |
91 | |
92 /////////////////////////////////////////////////////////////// | |
93 // | |
94 // class JvmtiFramePops - public methods | |
95 // | |
96 | |
97 JvmtiFramePops::JvmtiFramePops() { | |
6197 | 98 _pops = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int> (2, true); |
0 | 99 } |
100 | |
101 JvmtiFramePops::~JvmtiFramePops() { | |
102 // return memory to c_heap. | |
103 delete _pops; | |
104 } | |
105 | |
106 | |
107 #ifndef PRODUCT | |
108 void JvmtiFramePops::print() { | |
109 ResourceMark rm; | |
110 | |
111 int n = _pops->length(); | |
112 for (int i=0; i<n; i++) { | |
113 JvmtiFramePop fp = JvmtiFramePop(_pops->at(i)); | |
114 tty->print("%d: ", i); | |
115 fp.print(); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17639
diff
changeset
|
116 tty->cr(); |
0 | 117 } |
118 } | |
119 #endif | |
120 | |
121 /////////////////////////////////////////////////////////////// | |
122 // | |
123 // class JvmtiEnvThreadState | |
124 // | |
125 // Instances of JvmtiEnvThreadState hang off of each JvmtiThreadState, | |
126 // one per JvmtiEnv. | |
127 // | |
128 | |
129 JvmtiEnvThreadState::JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env) : | |
130 _event_enable() { | |
131 _thread = thread; | |
132 _env = (JvmtiEnv*)env; | |
133 _next = NULL; | |
134 _frame_pops = NULL; | |
135 _current_bci = 0; | |
136 _current_method_id = NULL; | |
137 _breakpoint_posted = false; | |
138 _single_stepping_posted = false; | |
139 _agent_thread_local_storage_data = NULL; | |
140 } | |
141 | |
142 JvmtiEnvThreadState::~JvmtiEnvThreadState() { | |
143 delete _frame_pops; | |
144 _frame_pops = NULL; | |
145 } | |
146 | |
147 // Given that a new (potential) event has come in, | |
148 // maintain the current JVMTI location on a per-thread per-env basis | |
149 // and use it to filter out duplicate events: | |
150 // - instruction rewrites | |
151 // - breakpoint followed by single step | |
152 // - single step at a breakpoint | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
153 void JvmtiEnvThreadState::compare_and_set_current_location(Method* new_method, |
0 | 154 address new_location, jvmtiEvent event) { |
155 | |
156 int new_bci = new_location - new_method->code_base(); | |
157 | |
158 // The method is identified and stored as a jmethodID which is safe in this | |
159 // case because the class cannot be unloaded while a method is executing. | |
160 jmethodID new_method_id = new_method->jmethod_id(); | |
161 | |
162 // the last breakpoint or single step was at this same location | |
163 if (_current_bci == new_bci && _current_method_id == new_method_id) { | |
164 switch (event) { | |
165 case JVMTI_EVENT_BREAKPOINT: | |
166 // Repeat breakpoint is complicated. If we previously posted a breakpoint | |
167 // event at this location and if we also single stepped at this location | |
168 // then we skip the duplicate breakpoint. | |
169 _breakpoint_posted = _breakpoint_posted && _single_stepping_posted; | |
170 break; | |
171 case JVMTI_EVENT_SINGLE_STEP: | |
172 // Repeat single step is easy: just don't post it again. | |
173 // If step is pending for popframe then it may not be | |
174 // a repeat step. The new_bci and method_id is same as current_bci | |
175 // and current method_id after pop and step for recursive calls. | |
176 // This has been handled by clearing the location | |
177 _single_stepping_posted = true; | |
178 break; | |
179 default: | |
180 assert(false, "invalid event value passed"); | |
181 break; | |
182 } | |
183 return; | |
184 } | |
185 | |
186 set_current_location(new_method_id, new_bci); | |
187 _breakpoint_posted = false; | |
188 _single_stepping_posted = false; | |
189 } | |
190 | |
191 | |
192 JvmtiFramePops* JvmtiEnvThreadState::get_frame_pops() { | |
193 #ifdef ASSERT | |
194 uint32_t debug_bits = 0; | |
195 #endif | |
196 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), | |
197 "frame pop data only accessible from same thread or while suspended"); | |
198 | |
199 if (_frame_pops == NULL) { | |
200 _frame_pops = new JvmtiFramePops(); | |
201 assert(_frame_pops != NULL, "_frame_pops != NULL"); | |
202 } | |
203 return _frame_pops; | |
204 } | |
205 | |
206 | |
207 bool JvmtiEnvThreadState::has_frame_pops() { | |
208 return _frame_pops == NULL? false : (_frame_pops->length() > 0); | |
209 } | |
210 | |
211 void JvmtiEnvThreadState::set_frame_pop(int frame_number) { | |
212 #ifdef ASSERT | |
213 uint32_t debug_bits = 0; | |
214 #endif | |
215 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), | |
216 "frame pop data only accessible from same thread or while suspended"); | |
217 JvmtiFramePop fpop(frame_number); | |
218 JvmtiEventController::set_frame_pop(this, fpop); | |
219 } | |
220 | |
221 | |
222 void JvmtiEnvThreadState::clear_frame_pop(int frame_number) { | |
223 #ifdef ASSERT | |
224 uint32_t debug_bits = 0; | |
225 #endif | |
226 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), | |
227 "frame pop data only accessible from same thread or while suspended"); | |
228 JvmtiFramePop fpop(frame_number); | |
229 JvmtiEventController::clear_frame_pop(this, fpop); | |
230 } | |
231 | |
232 | |
233 void JvmtiEnvThreadState::clear_to_frame_pop(int frame_number) { | |
234 #ifdef ASSERT | |
235 uint32_t debug_bits = 0; | |
236 #endif | |
237 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), | |
238 "frame pop data only accessible from same thread or while suspended"); | |
239 JvmtiFramePop fpop(frame_number); | |
240 JvmtiEventController::clear_to_frame_pop(this, fpop); | |
241 } | |
242 | |
243 | |
244 bool JvmtiEnvThreadState::is_frame_pop(int cur_frame_number) { | |
245 #ifdef ASSERT | |
246 uint32_t debug_bits = 0; | |
247 #endif | |
248 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), | |
249 "frame pop data only accessible from same thread or while suspended"); | |
250 if (!get_thread()->is_interp_only_mode() || _frame_pops == NULL) { | |
251 return false; | |
252 } | |
253 JvmtiFramePop fp(cur_frame_number); | |
254 return get_frame_pops()->contains(fp); | |
255 } | |
256 | |
257 | |
258 class VM_GetCurrentLocation : public VM_Operation { | |
259 private: | |
260 JavaThread *_thread; | |
261 jmethodID _method_id; | |
262 int _bci; | |
263 | |
264 public: | |
265 VM_GetCurrentLocation(JavaThread *thread) { | |
266 _thread = thread; | |
267 } | |
268 VMOp_Type type() const { return VMOp_GetCurrentLocation; } | |
269 void doit() { | |
270 ResourceMark rmark; // _thread != Thread::current() | |
271 RegisterMap rm(_thread, false); | |
13415
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
272 // There can be a race condition between a VM_Operation reaching a safepoint |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
273 // and the target thread exiting from Java execution. |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
274 // We must recheck the last Java frame still exists. |
17639
7b35e546ba31
8030027: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Linux-amd64: SIGSEGV in JavaThread::last_java_vframe(RegisterMap*)+0xfa
sspitsyn
parents:
17467
diff
changeset
|
275 if (!_thread->is_exiting() && _thread->has_last_Java_frame()) { |
13415
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
276 javaVFrame* vf = _thread->last_java_vframe(&rm); |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
277 assert(vf != NULL, "must have last java frame"); |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
278 Method* method = vf->method(); |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
279 _method_id = method->jmethod_id(); |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
280 _bci = vf->bci(); |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
281 } else { |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
282 // Clear current location as the target thread has no Java frames anymore. |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
283 _method_id = (jmethodID)NULL; |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
284 _bci = 0; |
c8c2d6b82499
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents:
6725
diff
changeset
|
285 } |
0 | 286 } |
287 void get_current_location(jmethodID *method_id, int *bci) { | |
288 *method_id = _method_id; | |
289 *bci = _bci; | |
290 } | |
291 }; | |
292 | |
293 void JvmtiEnvThreadState::reset_current_location(jvmtiEvent event_type, bool enabled) { | |
294 assert(event_type == JVMTI_EVENT_SINGLE_STEP || event_type == JVMTI_EVENT_BREAKPOINT, | |
295 "must be single-step or breakpoint event"); | |
296 | |
297 // Current location is used to detect the following: | |
298 // 1) a breakpoint event followed by single-stepping to the same bci | |
299 // 2) single-step to a bytecode that will be transformed to a fast version | |
300 // We skip to avoid posting the duplicate single-stepping event. | |
301 | |
302 // If single-stepping is disabled, clear current location so that | |
303 // single-stepping to the same method and bcp at a later time will be | |
304 // detected if single-stepping is enabled at that time (see 4388912). | |
305 | |
306 // If single-stepping is enabled, set the current location to the | |
307 // current method and bcp. This covers the following type of case, | |
308 // e.g., the debugger stepi command: | |
309 // - bytecode single stepped | |
310 // - SINGLE_STEP event posted and SINGLE_STEP event disabled | |
311 // - SINGLE_STEP event reenabled | |
312 // - bytecode rewritten to fast version | |
313 | |
314 // If breakpoint event is disabled, clear current location only if | |
315 // single-stepping is not enabled. Otherwise, keep the thread location | |
316 // to detect any duplicate events. | |
317 | |
318 if (enabled) { | |
319 // If enabling breakpoint, no need to reset. | |
320 // Can't do anything if empty stack. | |
321 if (event_type == JVMTI_EVENT_SINGLE_STEP && _thread->has_last_Java_frame()) { | |
322 jmethodID method_id; | |
323 int bci; | |
324 // The java thread stack may not be walkable for a running thread | |
325 // so get current location at safepoint. | |
326 VM_GetCurrentLocation op(_thread); | |
327 VMThread::execute(&op); | |
328 op.get_current_location(&method_id, &bci); | |
329 set_current_location(method_id, bci); | |
330 } | |
331 } else if (event_type == JVMTI_EVENT_SINGLE_STEP || !is_enabled(JVMTI_EVENT_SINGLE_STEP)) { | |
332 // If this is to disable breakpoint, also check if single-step is not enabled | |
333 clear_current_location(); | |
334 } | |
335 } |