annotate src/share/vm/prims/jvmtiImpl.cpp @ 1716:be3f9c242c9d

6948538: CMS: BOT walkers can fall into object allocation and initialization cracks Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode. Reviewed-by: chrisphi, johnc, poonam
author ysr
date Mon, 16 Aug 2010 15:58:42 -0700
parents c18cbe5936b8
children fa83ab460c54 ce6848d0666d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 611
diff changeset
2 * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 611
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 611
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: 611
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_jvmtiImpl.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP) GrowableArray<JvmtiRawMonitor*>(1,true);
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30 void JvmtiPendingMonitors::transition_raw_monitors() {
a61af66fc99e Initial load
duke
parents:
diff changeset
31 assert((Threads::number_of_threads()==1),
a61af66fc99e Initial load
duke
parents:
diff changeset
32 "Java thread has not created yet or more than one java thread \
a61af66fc99e Initial load
duke
parents:
diff changeset
33 is running. Raw monitor transition will not work");
a61af66fc99e Initial load
duke
parents:
diff changeset
34 JavaThread *current_java_thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
35 assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
a61af66fc99e Initial load
duke
parents:
diff changeset
36 {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 ThreadBlockInVM __tbivm(current_java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
38 for(int i=0; i< count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 JvmtiRawMonitor *rmonitor = monitors()->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
40 int r = rmonitor->raw_enter(current_java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
41 assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
a61af66fc99e Initial load
duke
parents:
diff changeset
42 }
a61af66fc99e Initial load
duke
parents:
diff changeset
43 }
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // pending monitors are converted to real monitor so delete them all.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 dispose();
a61af66fc99e Initial load
duke
parents:
diff changeset
46 }
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 //
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // class JvmtiAgentThread
a61af66fc99e Initial load
duke
parents:
diff changeset
50 //
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // JavaThread used to wrap a thread started by an agent
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // using the JVMTI method RunAgentThread.
a61af66fc99e Initial load
duke
parents:
diff changeset
53 //
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg)
a61af66fc99e Initial load
duke
parents:
diff changeset
56 : JavaThread(start_function_wrapper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _env = env;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _start_fn = start_fn;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _start_arg = start_arg;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 void
a61af66fc99e Initial load
duke
parents:
diff changeset
63 JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // It is expected that any Agent threads will be created as
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // Java Threads. If this is the case, notification of the creation
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // of the thread is given in JavaThread::thread_main().
a61af66fc99e Initial load
duke
parents:
diff changeset
67 assert(thread->is_Java_thread(), "debugger thread should be a Java Thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
68 assert(thread == JavaThread::current(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 dthread->call_start_function();
a61af66fc99e Initial load
duke
parents:
diff changeset
72 }
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 void
a61af66fc99e Initial load
duke
parents:
diff changeset
75 JvmtiAgentThread::call_start_function() {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 ThreadToNativeFromVM transition(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 //
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // class GrowableCache - private methods
a61af66fc99e Initial load
duke
parents:
diff changeset
83 //
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 void GrowableCache::recache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
86 int len = _elements->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 FREE_C_HEAP_ARRAY(address, _cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
89 _cache = NEW_C_HEAP_ARRAY(address,len+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 for (int i=0; i<len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 _cache[i] = _elements->at(i)->getCacheValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
93 //
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // The cache entry has gone bad. Without a valid frame pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // value, the entry is useless so we simply delete it in product
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // mode. The call to remove() will rebuild the cache again
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // without the bad entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
98 //
a61af66fc99e Initial load
duke
parents:
diff changeset
99 if (_cache[i] == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 assert(false, "cannot recache NULL elements");
a61af66fc99e Initial load
duke
parents:
diff changeset
101 remove(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 _cache[len] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 _listener_fun(_this_obj,_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 bool GrowableCache::equals(void* v, GrowableElement *e2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 GrowableElement *e1 = (GrowableElement *) v;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 assert(e1 != NULL, "e1 != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
113 assert(e2 != NULL, "e2 != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 return e1->equals(e2);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 //
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // class GrowableCache - public methods
a61af66fc99e Initial load
duke
parents:
diff changeset
120 //
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 GrowableCache::GrowableCache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 _this_obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
124 _listener_fun = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
125 _elements = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
126 _cache = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 GrowableCache::~GrowableCache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
131 delete _elements;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 FREE_C_HEAP_ARRAY(address, _cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 _this_obj = this_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 _listener_fun = listener_fun;
a61af66fc99e Initial load
duke
parents:
diff changeset
138 _elements = new (ResourceObj::C_HEAP) GrowableArray<GrowableElement*>(5,true);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 recache();
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // number of elements in the collection
a61af66fc99e Initial load
duke
parents:
diff changeset
143 int GrowableCache::length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 return _elements->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // get the value of the index element in the collection
a61af66fc99e Initial load
duke
parents:
diff changeset
148 GrowableElement* GrowableCache::at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 GrowableElement *e = (GrowableElement *) _elements->at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
150 assert(e != NULL, "e != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return e;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 int GrowableCache::find(GrowableElement* e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 return _elements->find(e, GrowableCache::equals);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // append a copy of the element to the end of the collection
a61af66fc99e Initial load
duke
parents:
diff changeset
159 void GrowableCache::append(GrowableElement* e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 GrowableElement *new_e = e->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
161 _elements->append(new_e);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 recache();
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // insert a copy of the element using lessthan()
a61af66fc99e Initial load
duke
parents:
diff changeset
166 void GrowableCache::insert(GrowableElement* e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 GrowableElement *new_e = e->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
168 _elements->append(new_e);
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 int n = length()-2;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 for (int i=n; i>=0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 GrowableElement *e1 = _elements->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 GrowableElement *e2 = _elements->at(i+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 if (e2->lessThan(e1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 _elements->at_put(i+1, e1);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 _elements->at_put(i, e2);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 recache();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // remove the element at index
a61af66fc99e Initial load
duke
parents:
diff changeset
184 void GrowableCache::remove (int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 GrowableElement *e = _elements->at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 assert(e != NULL, "e != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
187 _elements->remove(e);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 delete e;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 recache();
a61af66fc99e Initial load
duke
parents:
diff changeset
190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // clear out all elements, release all heap space and
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // let our listener know that things have changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
194 void GrowableCache::clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 int len = _elements->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
196 for (int i=0; i<len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 delete _elements->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 _elements->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
200 recache();
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void GrowableCache::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 int len = _elements->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
205 for (int i=0; i<len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 GrowableElement *e = _elements->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 e->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 void GrowableCache::gc_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 int len = _elements->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // recompute the new cache value after GC
a61af66fc99e Initial load
duke
parents:
diff changeset
214 for (int i=0; i<len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 _cache[i] = _elements->at(i)->getCacheValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 //
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // class JvmtiRawMonitor
a61af66fc99e Initial load
duke
parents:
diff changeset
222 //
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
226 _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1), name);
a61af66fc99e Initial load
duke
parents:
diff changeset
227 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
228 _name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
230 _magic = JVMTI_RM_MAGIC;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 JvmtiRawMonitor::~JvmtiRawMonitor() {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
235 FreeHeap(_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
236 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
237 _magic = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240
611
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
241 bool
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
242 JvmtiRawMonitor::is_valid() {
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
243 int value = 0;
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
244
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
245 // This object might not be a JvmtiRawMonitor so we can't assume
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
246 // the _magic field is properly aligned. Get the value in a safe
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
247 // way and then check against JVMTI_RM_MAGIC.
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
248
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
249 switch (sizeof(_magic)) {
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
250 case 2:
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
251 value = Bytes::get_native_u2((address)&_magic);
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
252 break;
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
253
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
254 case 4:
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
255 value = Bytes::get_native_u4((address)&_magic);
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
256 break;
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
257
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
258 case 8:
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
259 value = Bytes::get_native_u8((address)&_magic);
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
260 break;
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
261
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
262 default:
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
263 guarantee(false, "_magic field is an unexpected size");
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
264 }
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
265
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
266 return value == JVMTI_RM_MAGIC;
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
267 }
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
268
2f716c0acb64 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 0
diff changeset
269
0
a61af66fc99e Initial load
duke
parents:
diff changeset
270 //
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // class JvmtiBreakpoint
a61af66fc99e Initial load
duke
parents:
diff changeset
272 //
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 JvmtiBreakpoint::JvmtiBreakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 _method = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
276 _bci = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 #ifdef CHECK_UNHANDLED_OOPS
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // This one is always allocated with new, but check it just in case.
a61af66fc99e Initial load
duke
parents:
diff changeset
279 Thread *thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
280 if (thread->is_in_stack((address)&_method)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 thread->allow_unhandled_oop((oop*)&_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 #endif // CHECK_UNHANDLED_OOPS
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 JvmtiBreakpoint::JvmtiBreakpoint(methodOop m_method, jlocation location) {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 _method = m_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 assert(_method != NULL, "_method != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
289 _bci = (int) location;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 #ifdef CHECK_UNHANDLED_OOPS
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // Could be allocated with new and wouldn't be on the unhandled oop list.
a61af66fc99e Initial load
duke
parents:
diff changeset
292 Thread *thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
293 if (thread->is_in_stack((address)&_method)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 thread->allow_unhandled_oop(&_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
296 #endif // CHECK_UNHANDLED_OOPS
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 assert(_bci >= 0, "_bci >= 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 _method = bp._method;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 _bci = bp._bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
308 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310
a61af66fc99e Initial load
duke
parents:
diff changeset
311 bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 return _method == bp._method
a61af66fc99e Initial load
duke
parents:
diff changeset
313 && _bci == bp._bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 bool JvmtiBreakpoint::is_valid() {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 return _method != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
318 _bci >= 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 address JvmtiBreakpoint::getBcp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 return _method->bcp_from(_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 ((methodOopDesc*)_method->*meth_act)(_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // add/remove breakpoint to/from versions of the method that
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // are EMCP. Directly or transitively obsolete methods are
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // not saved in the PreviousVersionInfo.
a61af66fc99e Initial load
duke
parents:
diff changeset
331 Thread *thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
332 instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
333 symbolOop m_name = _method->name();
a61af66fc99e Initial load
duke
parents:
diff changeset
334 symbolOop m_signature = _method->signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // PreviousVersionInfo objects returned via PreviousVersionWalker
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // contain a GrowableArray of handles. We have to clean up the
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // GrowableArray _after_ the PreviousVersionWalker destructor
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // has destroyed the handles.
a61af66fc99e Initial load
duke
parents:
diff changeset
342 {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // search previous versions if they exist
a61af66fc99e Initial load
duke
parents:
diff changeset
344 PreviousVersionWalker pvw((instanceKlass *)ikh()->klass_part());
a61af66fc99e Initial load
duke
parents:
diff changeset
345 for (PreviousVersionInfo * pv_info = pvw.next_previous_version();
a61af66fc99e Initial load
duke
parents:
diff changeset
346 pv_info != NULL; pv_info = pvw.next_previous_version()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
347 GrowableArray<methodHandle>* methods =
a61af66fc99e Initial load
duke
parents:
diff changeset
348 pv_info->prev_EMCP_method_handles();
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (methods == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // We have run into a PreviousVersion generation where
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // all methods were made obsolete during that generation's
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // RedefineClasses() operation. At the time of that
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // operation, all EMCP methods were flushed so we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // have to go back any further.
a61af66fc99e Initial load
duke
parents:
diff changeset
356 //
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // A NULL methods array is different than an empty methods
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // array. We cannot infer any optimizations about older
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // generations from an empty methods array for the current
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
361 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 for (int i = methods->length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 methodHandle method = methods->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
366 if (method->name() == m_name && method->signature() == m_signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
a61af66fc99e Initial load
duke
parents:
diff changeset
368 meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear",
a61af66fc99e Initial load
duke
parents:
diff changeset
369 method->name()->as_C_string(),
a61af66fc99e Initial load
duke
parents:
diff changeset
370 method->signature()->as_C_string()));
a61af66fc99e Initial load
duke
parents:
diff changeset
371 assert(!method->is_obsolete(), "only EMCP methods here");
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 ((methodOopDesc*)method()->*meth_act)(_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 } // pvw is cleaned up
a61af66fc99e Initial load
duke
parents:
diff changeset
379 } // rm is cleaned up
a61af66fc99e Initial load
duke
parents:
diff changeset
380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 void JvmtiBreakpoint::set() {
a61af66fc99e Initial load
duke
parents:
diff changeset
383 each_method_version_do(&methodOopDesc::set_breakpoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 void JvmtiBreakpoint::clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 each_method_version_do(&methodOopDesc::clear_breakpoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 void JvmtiBreakpoint::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
392 const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
393 const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
394
a61af66fc99e Initial load
duke
parents:
diff changeset
395 tty->print("Breakpoint(%s,%s,%d,%p)",class_name, method_name, _bci, getBcp());
a61af66fc99e Initial load
duke
parents:
diff changeset
396 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 //
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // class VM_ChangeBreakpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
402 //
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // Modify the Breakpoints data structure at a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
404 //
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 void VM_ChangeBreakpoints::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 switch (_operation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 case SET_BREAKPOINT:
a61af66fc99e Initial load
duke
parents:
diff changeset
409 _breakpoints->set_at_safepoint(*_bp);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 case CLEAR_BREAKPOINT:
a61af66fc99e Initial load
duke
parents:
diff changeset
412 _breakpoints->clear_at_safepoint(*_bp);
a61af66fc99e Initial load
duke
parents:
diff changeset
413 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
414 case CLEAR_ALL_BREAKPOINT:
a61af66fc99e Initial load
duke
parents:
diff changeset
415 _breakpoints->clearall_at_safepoint();
a61af66fc99e Initial load
duke
parents:
diff changeset
416 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
418 assert(false, "Unknown operation");
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 void VM_ChangeBreakpoints::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // This operation keeps breakpoints alive
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if (_breakpoints != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 _breakpoints->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (_bp != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 _bp->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 //
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // class JvmtiBreakpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
434 //
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // a JVMTI internal collection of JvmtiBreakpoint
a61af66fc99e Initial load
duke
parents:
diff changeset
436 //
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 _bps.initialize(this,listener_fun);
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 JvmtiBreakpoints:: ~JvmtiBreakpoints() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 void JvmtiBreakpoints::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 _bps.oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 void JvmtiBreakpoints::gc_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 _bps.gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 void JvmtiBreakpoints::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
454 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 int n = _bps.length();
a61af66fc99e Initial load
duke
parents:
diff changeset
457 for (int i=0; i<n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 JvmtiBreakpoint& bp = _bps.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
459 tty->print("%d: ", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
460 bp.print();
a61af66fc99e Initial load
duke
parents:
diff changeset
461 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
468 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
469
a61af66fc99e Initial load
duke
parents:
diff changeset
470 int i = _bps.find(bp);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 if (i == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 _bps.append(bp);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 bp.set();
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
476
a61af66fc99e Initial load
duke
parents:
diff changeset
477 void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
478 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 int i = _bps.find(bp);
a61af66fc99e Initial load
duke
parents:
diff changeset
481 if (i != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
482 _bps.remove(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
483 bp.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 void JvmtiBreakpoints::clearall_at_safepoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 int len = _bps.length();
a61af66fc99e Initial load
duke
parents:
diff changeset
491 for (int i=0; i<len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 _bps.at(i).clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494 _bps.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497 int JvmtiBreakpoints::length() { return _bps.length(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 if ( _bps.find(bp) != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 return JVMTI_ERROR_DUPLICATE;
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503 VM_ChangeBreakpoints set_breakpoint(this,VM_ChangeBreakpoints::SET_BREAKPOINT, &bp);
a61af66fc99e Initial load
duke
parents:
diff changeset
504 VMThread::execute(&set_breakpoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 return JVMTI_ERROR_NONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 if ( _bps.find(bp) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
510 return JVMTI_ERROR_NOT_FOUND;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 VM_ChangeBreakpoints clear_breakpoint(this,VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp);
a61af66fc99e Initial load
duke
parents:
diff changeset
514 VMThread::execute(&clear_breakpoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
515 return JVMTI_ERROR_NONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 void JvmtiBreakpoints::clearall_in_class_at_safepoint(klassOop klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 bool changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // We are going to run thru the list of bkpts
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // and delete some. This deletion probably alters
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // the list in some implementation defined way such
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // that when we delete entry i, the next entry might
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // no longer be at i+1. To be safe, each time we delete
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // an entry, we'll just start again from the beginning.
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // We'll stop when we make a pass thru the whole list without
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // deleting anything.
a61af66fc99e Initial load
duke
parents:
diff changeset
528 while (changed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 int len = _bps.length();
a61af66fc99e Initial load
duke
parents:
diff changeset
530 changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 JvmtiBreakpoint& bp = _bps.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 if (bp.method()->method_holder() == klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 bp.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
535 _bps.remove(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // This changed 'i' so we have to start over.
a61af66fc99e Initial load
duke
parents:
diff changeset
537 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543
a61af66fc99e Initial load
duke
parents:
diff changeset
544 void JvmtiBreakpoints::clearall() {
a61af66fc99e Initial load
duke
parents:
diff changeset
545 VM_ChangeBreakpoints clearall_breakpoint(this,VM_ChangeBreakpoints::CLEAR_ALL_BREAKPOINT);
a61af66fc99e Initial load
duke
parents:
diff changeset
546 VMThread::execute(&clearall_breakpoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
548
a61af66fc99e Initial load
duke
parents:
diff changeset
549 //
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // class JvmtiCurrentBreakpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
551 //
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
554 address * JvmtiCurrentBreakpoints::_breakpoint_list = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 _jvmti_breakpoints = new JvmtiBreakpoints(listener_fun);
a61af66fc99e Initial load
duke
parents:
diff changeset
560 assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
561 return (*_jvmti_breakpoints);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 void JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 assert(this_jvmti != NULL, "this_jvmti != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 debug_only(int n = this_jvmti->length(););
a61af66fc99e Initial load
duke
parents:
diff changeset
569 assert(cache[n] == NULL, "cache must be NULL terminated");
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 set_breakpoint_list(cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
573
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
576 if (_jvmti_breakpoints != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 _jvmti_breakpoints->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 void JvmtiCurrentBreakpoints::gc_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if (_jvmti_breakpoints != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 _jvmti_breakpoints->gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587
a61af66fc99e Initial load
duke
parents:
diff changeset
588 ///////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
589 //
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // class VM_GetOrSetLocal
a61af66fc99e Initial load
duke
parents:
diff changeset
591 //
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // Constructor for non-object getter
a61af66fc99e Initial load
duke
parents:
diff changeset
594 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type)
a61af66fc99e Initial load
duke
parents:
diff changeset
595 : _thread(thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
596 , _calling_thread(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
597 , _depth(depth)
a61af66fc99e Initial load
duke
parents:
diff changeset
598 , _index(index)
a61af66fc99e Initial load
duke
parents:
diff changeset
599 , _type(type)
a61af66fc99e Initial load
duke
parents:
diff changeset
600 , _set(false)
a61af66fc99e Initial load
duke
parents:
diff changeset
601 , _jvf(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
602 , _result(JVMTI_ERROR_NONE)
a61af66fc99e Initial load
duke
parents:
diff changeset
603 {
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // Constructor for object or non-object setter
a61af66fc99e Initial load
duke
parents:
diff changeset
607 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value)
a61af66fc99e Initial load
duke
parents:
diff changeset
608 : _thread(thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
609 , _calling_thread(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
610 , _depth(depth)
a61af66fc99e Initial load
duke
parents:
diff changeset
611 , _index(index)
a61af66fc99e Initial load
duke
parents:
diff changeset
612 , _type(type)
a61af66fc99e Initial load
duke
parents:
diff changeset
613 , _value(value)
a61af66fc99e Initial load
duke
parents:
diff changeset
614 , _set(true)
a61af66fc99e Initial load
duke
parents:
diff changeset
615 , _jvf(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
616 , _result(JVMTI_ERROR_NONE)
a61af66fc99e Initial load
duke
parents:
diff changeset
617 {
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // Constructor for object getter
a61af66fc99e Initial load
duke
parents:
diff changeset
621 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index)
a61af66fc99e Initial load
duke
parents:
diff changeset
622 : _thread(thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
623 , _calling_thread(calling_thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
624 , _depth(depth)
a61af66fc99e Initial load
duke
parents:
diff changeset
625 , _index(index)
a61af66fc99e Initial load
duke
parents:
diff changeset
626 , _type(T_OBJECT)
a61af66fc99e Initial load
duke
parents:
diff changeset
627 , _set(false)
a61af66fc99e Initial load
duke
parents:
diff changeset
628 , _jvf(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
629 , _result(JVMTI_ERROR_NONE)
a61af66fc99e Initial load
duke
parents:
diff changeset
630 {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633
a61af66fc99e Initial load
duke
parents:
diff changeset
634 vframe *VM_GetOrSetLocal::get_vframe() {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 if (!_thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
636 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
638 RegisterMap reg_map(_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
639 vframe *vf = _thread->last_java_vframe(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
640 int d = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 while ((vf != NULL) && (d < _depth)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 vf = vf->java_sender();
a61af66fc99e Initial load
duke
parents:
diff changeset
643 d++;
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645 return vf;
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 javaVFrame *VM_GetOrSetLocal::get_java_vframe() {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 vframe* vf = get_vframe();
a61af66fc99e Initial load
duke
parents:
diff changeset
650 if (vf == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 _result = JVMTI_ERROR_NO_MORE_FRAMES;
a61af66fc99e Initial load
duke
parents:
diff changeset
652 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654 javaVFrame *jvf = (javaVFrame*)vf;
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 if (!vf->is_java_frame() || jvf->method()->is_native()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
657 _result = JVMTI_ERROR_OPAQUE_FRAME;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
660 return jvf;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // Check that the klass is assignable to a type with the given signature.
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // Another solution could be to use the function Klass::is_subtype_of(type).
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // But the type class can be forced to load/initialize eagerly in such a case.
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // This may cause unexpected consequences like CFLH or class-init JVMTI events.
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // It is better to avoid such a behavior.
a61af66fc99e Initial load
duke
parents:
diff changeset
668 bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
669 assert(ty_sign != NULL, "type signature must not be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 assert(thread != NULL, "thread must not be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
671 assert(klass != NULL, "klass must not be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
672
a61af66fc99e Initial load
duke
parents:
diff changeset
673 int len = (int) strlen(ty_sign);
a61af66fc99e Initial load
duke
parents:
diff changeset
674 if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name
a61af66fc99e Initial load
duke
parents:
diff changeset
675 ty_sign++;
a61af66fc99e Initial load
duke
parents:
diff changeset
676 len -= 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
678 symbolHandle ty_sym = oopFactory::new_symbol_handle(ty_sign, len, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
679 if (klass->name() == ty_sym()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // Compare primary supers
a61af66fc99e Initial load
duke
parents:
diff changeset
683 int super_depth = klass->super_depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
684 int idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
685 for (idx = 0; idx < super_depth; idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
686 if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // Compare secondary supers
a61af66fc99e Initial load
duke
parents:
diff changeset
691 objArrayOop sec_supers = klass->secondary_supers();
a61af66fc99e Initial load
duke
parents:
diff changeset
692 for (idx = 0; idx < sec_supers->length(); idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 if (Klass::cast((klassOop) sec_supers->obj_at(idx))->name() == ty_sym()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // Checks error conditions:
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // JVMTI_ERROR_INVALID_SLOT
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // JVMTI_ERROR_TYPE_MISMATCH
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // Returns: 'true' - everything is Ok, 'false' - error code
a61af66fc99e Initial load
duke
parents:
diff changeset
704
a61af66fc99e Initial load
duke
parents:
diff changeset
705 bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
706 methodOop method_oop = jvf->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
707 if (!method_oop->has_localvariable_table()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // Just to check index boundaries
a61af66fc99e Initial load
duke
parents:
diff changeset
709 jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
710 if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 _result = JVMTI_ERROR_INVALID_SLOT;
a61af66fc99e Initial load
duke
parents:
diff changeset
712 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
714 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 jint num_entries = method_oop->localvariable_table_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if (num_entries == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 _result = JVMTI_ERROR_INVALID_SLOT;
a61af66fc99e Initial load
duke
parents:
diff changeset
720 return false; // There are no slots
a61af66fc99e Initial load
duke
parents:
diff changeset
721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
722 int signature_idx = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 int vf_bci = jvf->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
724 LocalVariableTableElement* table = method_oop->localvariable_table_start();
a61af66fc99e Initial load
duke
parents:
diff changeset
725 for (int i = 0; i < num_entries; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
726 int start_bci = table[i].start_bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
727 int end_bci = start_bci + table[i].length;
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // Here we assume that locations of LVT entries
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // with the same slot number cannot be overlapped
a61af66fc99e Initial load
duke
parents:
diff changeset
731 if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 signature_idx = (int) table[i].descriptor_cp_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
733 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
736 if (signature_idx == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 _result = JVMTI_ERROR_INVALID_SLOT;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 return false; // Incorrect slot index
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740 symbolOop sign_sym = method_oop->constants()->symbol_at(signature_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 const char* signature = (const char *) sign_sym->as_utf8();
a61af66fc99e Initial load
duke
parents:
diff changeset
742 BasicType slot_type = char2type(signature[0]);
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 switch (slot_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
745 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
746 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
747 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
748 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
749 slot_type = T_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
750 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
751 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
752 slot_type = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 };
a61af66fc99e Initial load
duke
parents:
diff changeset
755 if (_type != slot_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
756 _result = JVMTI_ERROR_TYPE_MISMATCH;
a61af66fc99e Initial load
duke
parents:
diff changeset
757 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
759
a61af66fc99e Initial load
duke
parents:
diff changeset
760 jobject jobj = _value.l;
a61af66fc99e Initial load
duke
parents:
diff changeset
761 if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // Check that the jobject class matches the return type signature.
a61af66fc99e Initial load
duke
parents:
diff changeset
763 JavaThread* cur_thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
764 HandleMark hm(cur_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 Handle obj = Handle(cur_thread, JNIHandles::resolve_external_guard(jobj));
a61af66fc99e Initial load
duke
parents:
diff changeset
767 NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
a61af66fc99e Initial load
duke
parents:
diff changeset
768 KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
769 NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 if (!is_assignable(signature, Klass::cast(ob_kh()), cur_thread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 _result = JVMTI_ERROR_TYPE_MISMATCH;
a61af66fc99e Initial load
duke
parents:
diff changeset
773 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
776 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779 static bool can_be_deoptimized(vframe* vf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
a61af66fc99e Initial load
duke
parents:
diff changeset
781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
782
a61af66fc99e Initial load
duke
parents:
diff changeset
783 bool VM_GetOrSetLocal::doit_prologue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
784 _jvf = get_java_vframe();
a61af66fc99e Initial load
duke
parents:
diff changeset
785 NULL_CHECK(_jvf, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 if (!check_slot_type(_jvf)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
790 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 void VM_GetOrSetLocal::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
794 if (_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // Force deoptimization of frame if compiled because it's
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // possible the compiler emitted some locals as constant values,
a61af66fc99e Initial load
duke
parents:
diff changeset
797 // meaning they are not mutable.
a61af66fc99e Initial load
duke
parents:
diff changeset
798 if (can_be_deoptimized(_jvf)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 // Schedule deoptimization so that eventually the local
a61af66fc99e Initial load
duke
parents:
diff changeset
801 // update will be written to an interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
802 VM_DeoptimizeFrame deopt(_jvf->thread(), _jvf->fr().id());
a61af66fc99e Initial load
duke
parents:
diff changeset
803 VMThread::execute(&deopt);
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // Now store a new value for the local which will be applied
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // once deoptimization occurs. Note however that while this
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // write is deferred until deoptimization actually happens
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // can vframe created after this point will have its locals
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // reflecting this update so as far as anyone can see the
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // write has already taken place.
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // If we are updating an oop then get the oop from the handle
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // since the handle will be long gone by the time the deopt
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // happens. The oop stored in the deferred local will be
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // gc'd on its own.
a61af66fc99e Initial load
duke
parents:
diff changeset
816 if (_type == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
817 _value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l));
a61af66fc99e Initial load
duke
parents:
diff changeset
818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // Re-read the vframe so we can see that it is deoptimized
a61af66fc99e Initial load
duke
parents:
diff changeset
820 // [ Only need because of assert in update_local() ]
a61af66fc99e Initial load
duke
parents:
diff changeset
821 _jvf = get_java_vframe();
a61af66fc99e Initial load
duke
parents:
diff changeset
822 ((compiledVFrame*)_jvf)->update_local(_type, _index, _value);
a61af66fc99e Initial load
duke
parents:
diff changeset
823 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825 StackValueCollection *locals = _jvf->locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
826 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
827
a61af66fc99e Initial load
duke
parents:
diff changeset
828 switch (_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
829 case T_INT: locals->set_int_at (_index, _value.i); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
830 case T_LONG: locals->set_long_at (_index, _value.j); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
831 case T_FLOAT: locals->set_float_at (_index, _value.f); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
832 case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
833 case T_OBJECT: {
a61af66fc99e Initial load
duke
parents:
diff changeset
834 Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
a61af66fc99e Initial load
duke
parents:
diff changeset
835 locals->set_obj_at (_index, ob_h);
a61af66fc99e Initial load
duke
parents:
diff changeset
836 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
838 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840 _jvf->set_locals(locals);
a61af66fc99e Initial load
duke
parents:
diff changeset
841 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
842 StackValueCollection *locals = _jvf->locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844 if (locals->at(_index)->type() == T_CONFLICT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 memset(&_value, 0, sizeof(_value));
a61af66fc99e Initial load
duke
parents:
diff changeset
846 _value.l = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
847 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 switch (_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 case T_INT: _value.i = locals->int_at (_index); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
852 case T_LONG: _value.j = locals->long_at (_index); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
853 case T_FLOAT: _value.f = locals->float_at (_index); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
854 case T_DOUBLE: _value.d = locals->double_at(_index); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
855 case T_OBJECT: {
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // Wrap the oop to be returned in a local JNI handle since
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // oops_do() no longer applies after doit() is finished.
a61af66fc99e Initial load
duke
parents:
diff changeset
858 oop obj = locals->obj_at(_index)();
a61af66fc99e Initial load
duke
parents:
diff changeset
859 _value.l = JNIHandles::make_local(_calling_thread, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
860 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 bool VM_GetOrSetLocal::allow_nested_vm_operations() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
869 return true; // May need to deoptimize
a61af66fc99e Initial load
duke
parents:
diff changeset
870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 /////////////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
874
a61af66fc99e Initial load
duke
parents:
diff changeset
875 //
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // class JvmtiSuspendControl - see comments in jvmtiImpl.hpp
a61af66fc99e Initial load
duke
parents:
diff changeset
877 //
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 bool JvmtiSuspendControl::suspend(JavaThread *java_thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // external suspend should have caught suspending a thread twice
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // Immediate suspension required for JPDA back-end so JVMTI agent threads do
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // not deadlock due to later suspension on transitions while holding
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // raw monitors. Passing true causes the immediate suspension.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // java_suspend() will catch threads in the process of exiting
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // and will ignore them.
a61af66fc99e Initial load
duke
parents:
diff changeset
887 java_thread->java_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // It would be nice to have the following assertion in all the time,
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // but it is possible for a racing resume request to have resumed
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // this thread right after we suspended it. Temporarily enable this
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // assertion if you are chasing a different kind of bug.
a61af66fc99e Initial load
duke
parents:
diff changeset
893 //
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // java_thread->is_being_ext_suspended(), "thread is not suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
896
a61af66fc99e Initial load
duke
parents:
diff changeset
897 if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // check again because we can get delayed in java_suspend():
a61af66fc99e Initial load
duke
parents:
diff changeset
899 // the thread is in process of exiting.
a61af66fc99e Initial load
duke
parents:
diff changeset
900 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
902
a61af66fc99e Initial load
duke
parents:
diff changeset
903 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 bool JvmtiSuspendControl::resume(JavaThread *java_thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 // external suspend should have caught resuming a thread twice
a61af66fc99e Initial load
duke
parents:
diff changeset
908 assert(java_thread->is_being_ext_suspended(), "thread should be suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
909
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // resume thread
a61af66fc99e Initial load
duke
parents:
diff changeset
911 {
a61af66fc99e Initial load
duke
parents:
diff changeset
912 // must always grab Threads_lock, see JVM_SuspendThread
a61af66fc99e Initial load
duke
parents:
diff changeset
913 MutexLocker ml(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 java_thread->java_resume();
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920
a61af66fc99e Initial load
duke
parents:
diff changeset
921 void JvmtiSuspendControl::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
922 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
923 MutexLocker mu(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
924 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
925
a61af66fc99e Initial load
duke
parents:
diff changeset
926 tty->print("Suspended Threads: [");
a61af66fc99e Initial load
duke
parents:
diff changeset
927 for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 #if JVMTI_TRACE
a61af66fc99e Initial load
duke
parents:
diff changeset
929 const char *name = JvmtiTrace::safe_get_thread_name(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
930 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
931 const char *name = "";
a61af66fc99e Initial load
duke
parents:
diff changeset
932 #endif /*JVMTI_TRACE */
a61af66fc99e Initial load
duke
parents:
diff changeset
933 tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_');
a61af66fc99e Initial load
duke
parents:
diff changeset
934 if (!thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 tty->print("no stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
937 tty->print(") ");
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939 tty->print_cr("]");
a61af66fc99e Initial load
duke
parents:
diff changeset
940 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }