1 /*
2 * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "classfile/javaClasses.inline.hpp"
26 #include "classfile/vmClasses.hpp"
27 #include "classfile/vmSymbols.hpp"
28 #include "logging/log.hpp"
29 #include "logging/logStream.hpp"
30 #include "memory/oopFactory.hpp"
31 #include "memory/universe.hpp"
32 #include "oops/klass.inline.hpp"
33 #include "oops/method.inline.hpp"
34 #include "oops/objArrayOop.inline.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "prims/stackwalk.hpp"
37 #include "runtime/continuationJavaClasses.inline.hpp"
38 #include "runtime/globals.hpp"
39 #include "runtime/handles.inline.hpp"
40 #include "runtime/javaCalls.hpp"
41 #include "runtime/javaThread.hpp"
42 #include "runtime/keepStackGCProcessed.hpp"
43 #include "runtime/stackWatermarkSet.hpp"
44 #include "runtime/vframe.inline.hpp"
45 #include "utilities/formatBuffer.hpp"
46 #include "utilities/globalDefinitions.hpp"
47
48 // setup and cleanup actions
49 BaseFrameStream::BaseFrameStream(JavaThread* thread, Handle continuation)
50 : _thread(thread), _continuation(continuation), _anchor(0L) {
51 assert(thread != nullptr, "");
52 }
53
54 void BaseFrameStream::setup_magic_on_entry(refArrayHandle frames_array) {
55 frames_array->obj_at_put(magic_pos, _thread->threadObj());
56 _anchor = address_value();
57 assert(check_magic(frames_array), "invalid magic");
58 }
59
60 bool BaseFrameStream::check_magic(refArrayHandle frames_array) {
61 oop m1 = frames_array->obj_at(magic_pos);
62 jlong m2 = _anchor;
63 if (m1 == _thread->threadObj() && m2 == address_value()) return true;
64 return false;
65 }
66
67 bool BaseFrameStream::cleanup_magic_on_exit(refArrayHandle frames_array) {
68 bool ok = check_magic(frames_array);
69 frames_array->obj_at_put(magic_pos, nullptr);
70 _anchor = 0L;
71 return ok;
72 }
73
74 void BaseFrameStream::set_continuation(Handle cont) {
75 // ensure that the lifetime of the handle is that of the entire walk
76 // This actually also sets a copy of the handle in the RegisterMap,
77 // but that's OK, because we want them to be the same, anyway.
78 // (although we don't rely on this sharing, and set the other copy again)
79 _continuation.replace(cont());
80 }
81
82 JavaFrameStream::JavaFrameStream(JavaThread* thread, jint mode, Handle cont_scope, Handle cont)
83 : BaseFrameStream(thread, cont),
84 _vfst(cont.is_null()
85 ? vframeStream(thread, cont_scope)
86 : vframeStream(cont(), cont_scope)) {
87 _need_method_info = StackWalk::need_method_info(mode);
88 }
89
90 LiveFrameStream::LiveFrameStream(JavaThread* thread, RegisterMap* rm, Handle cont_scope, Handle cont)
91 : BaseFrameStream(thread, cont), _cont_scope(cont_scope) {
92
93 _map = rm;
94 if (cont.is_null()) {
95 _jvf = thread->last_java_vframe(rm);
96 _cont_entry = thread->last_continuation();
97 } else {
98 _jvf = Continuation::last_java_vframe(cont, rm);
99 _cont_entry = nullptr;
100 }
101 }
102
103 void JavaFrameStream::next() {
104 _vfst.next();
105 if (_vfst.method()->is_continuation_enter_intrinsic())
106 _vfst.next();
107 }
108
109 void LiveFrameStream::next() {
110 assert(_cont_scope.is_null() || cont() != (oop)nullptr, "must be");
111
112 oop cont = this->cont();
113 if (cont != (oop)nullptr && Continuation::is_continuation_entry_frame(_jvf->fr(), _jvf->register_map())) {
114 oop scope = jdk_internal_vm_Continuation::scope(cont);
115 if (_cont_scope.not_null() && scope == _cont_scope()) {
116 _jvf = nullptr;
117 return;
118 }
119 _cont_entry = _cont_entry->parent();
120 }
121 assert(!Continuation::is_scope_bottom(_cont_scope(), _jvf->fr(), _jvf->register_map()), "");
122
123 _jvf = _jvf->java_sender();
124 }
125
126 // Returns the BaseFrameStream for the current stack being traversed.
127 //
128 // Parameters:
129 // thread Current Java thread.
130 // magic Magic value used for each stack walking
131 // frames_array User-supplied buffers. The 0th element is reserved
132 // for this BaseFrameStream to use
133 //
134 BaseFrameStream* BaseFrameStream::from_current(JavaThread* thread, jlong magic,
135 refArrayHandle frames_array)
136 {
137 oop m1 = frames_array->obj_at(magic_pos);
138 if (m1 != thread->threadObj()) return nullptr;
139 if (magic == 0L) return nullptr;
140 BaseFrameStream* stream = (BaseFrameStream*) (intptr_t) magic;
141 if (!stream->is_valid_in(thread, frames_array)) return nullptr;
142 return stream;
143 }
144
145 // Unpacks one or more frames into user-supplied buffers.
146 // Updates the end index, and returns the number of unpacked frames.
147 // Always start with the existing vfst.method and bci.
148 // Do not call vfst.next to advance over the last returned value.
149 // In other words, do not leave any stale data in the vfst.
150 //
151 // Parameters:
152 // mode Restrict which frames to be decoded.
153 // BaseFrameStream stream of frames
154 // buffer_size Buffer size
155 // start_index Start index to the user-supplied buffers.
156 // frames_array Buffer to store stack frame information in, starting at start_index.
157 // frames array is a ClassFrameInfo[] array when only getting caller
158 // reference, and a StackFrameInfo[] array (or derivative)
159 // otherwise. It should never be null.
160 // end_index End index to the user-supplied buffers with unpacked frames.
161 //
162 // Returns the number of frames whose information was transferred into the buffers.
163 //
164 int StackWalk::fill_in_frames(jint mode, BaseFrameStream& stream,
165 int buffer_size, int start_index,
166 refArrayHandle frames_array,
167 int& end_index, TRAPS) {
168 log_debug(stackwalk)("fill_in_frames limit=%d start=%d frames length=%d",
169 buffer_size, start_index, frames_array->length());
170 assert(buffer_size > 0, "invalid buffer_size");
171 assert(buffer_size <= frames_array->length(), "oob");
172
173 int frames_decoded = 0;
174 for (; !stream.at_end(); stream.next()) {
175 if (stream.continuation() != nullptr && stream.continuation() != stream.reg_map()->cont()) {
176 // The code in StackStreamFactory.java has failed to set the continuation because frameBuffer.isAtBottom()
177 // returns false if the end of a continuation falls precisely at the end of the batch.
178 // By breaking here, we're signalling the Java code to set the continuation to the parent.
179 break;
180 }
181 assert(stream.continuation() == nullptr || stream.continuation() == stream.reg_map()->cont(), "");
182 Method* method = stream.method();
183
184 if (method == nullptr) continue;
185
186 // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES
187 // not set) and when StackWalker::getCallerClass is called
188 if (!ShowHiddenFrames && skip_hidden_frames(mode)) {
189 if (method->is_hidden()) {
190 log_debug(stackwalk)(" skip hidden method: %s", stream.method()->external_name());
191
192 // End a batch on continuation bottom to let the Java side to set the continuation to its parent and continue
193 if (stream.continuation() != nullptr && method->intrinsic_id() == vmIntrinsics::_Continuation_enter) break;
194 continue;
195 }
196 }
197
198 int index = end_index++;
199 log_debug(stackwalk)(" frame %d: %s bci %d", index, stream.method()->external_name(), stream.bci());
200 stream.fill_frame(index, frames_array, methodHandle(THREAD, method), CHECK_0);
201 frames_decoded++;
202
203 // End a batch on continuation bottom to let the Java side to set the continuation to its parent and continue
204 if (stream.continuation() != nullptr && method->intrinsic_id() == vmIntrinsics::_Continuation_enter) break;
205
206 if (end_index >= buffer_size) break;
207 }
208 log_debug(stackwalk)("fill_in_frames returns %d at_end=%d", frames_decoded, stream.at_end());
209
210 return frames_decoded;
211 }
212
213 // Fill in the LiveStackFrameInfo at the given index in frames_array
214 void LiveFrameStream::fill_frame(int index, refArrayHandle frames_array,
215 const methodHandle& method, TRAPS) {
216 HandleMark hm(THREAD);
217 Handle stackFrame(THREAD, frames_array->obj_at(index));
218 fill_live_stackframe(stackFrame, method, CHECK);
219 }
220
221 // Fill in the StackFrameInfo at the given index in frames_array
222 void JavaFrameStream::fill_frame(int index, refArrayHandle frames_array,
223 const methodHandle& method, TRAPS) {
224 if (_need_method_info) {
225 HandleMark hm(THREAD);
226 Handle stackFrame(THREAD, frames_array->obj_at(index));
227 fill_stackframe(stackFrame, method, CHECK);
228 } else {
229 HandleMark hm(THREAD);
230 Handle stackFrame(THREAD, frames_array->obj_at(index));
231 java_lang_ClassFrameInfo::init_class(stackFrame, method);
232 }
233 }
234
235 // Create and return a LiveStackFrame.PrimitiveSlot (if needed) for the
236 // StackValue at the given index. 'type' is expected to be T_INT, T_LONG,
237 // T_OBJECT, or T_CONFLICT.
238 oop LiveFrameStream::create_primitive_slot_instance(StackValueCollection* values,
239 int i, BasicType type, TRAPS) {
240 Klass* k = vmClasses::LiveStackFrameInfo_klass();
241 InstanceKlass* ik = InstanceKlass::cast(k);
242
243 JavaValue result(T_OBJECT);
244 JavaCallArguments args;
245 Symbol* signature = nullptr;
246
247 // ## TODO: type is only available in LocalVariable table, if present.
248 // ## StackValue type is T_INT or T_OBJECT (or converted to T_LONG on 64-bit)
249 switch (type) {
250 case T_INT:
251 args.push_int(values->int_at(i));
252 signature = vmSymbols::asPrimitive_int_signature();
253 break;
254
255 case T_LONG:
256 args.push_long(values->long_at(i));
257 signature = vmSymbols::asPrimitive_long_signature();
258 break;
259
260 case T_FLOAT:
261 case T_DOUBLE:
262 case T_BYTE:
263 case T_SHORT:
264 case T_CHAR:
265 case T_BOOLEAN:
266 THROW_MSG_(vmSymbols::java_lang_InternalError(), "Unexpected StackValue type", nullptr);
267
268 case T_OBJECT:
269 return values->obj_at(i)();
270
271 case T_CONFLICT:
272 // put a non-null slot
273 #ifdef _LP64
274 args.push_long(0);
275 signature = vmSymbols::asPrimitive_long_signature();
276 #else
277 args.push_int(0);
278 signature = vmSymbols::asPrimitive_int_signature();
279 #endif
280
281 break;
282
283 default: ShouldNotReachHere();
284 }
285 JavaCalls::call_static(&result,
286 ik,
287 vmSymbols::asPrimitive_name(),
288 signature,
289 &args,
290 CHECK_NULL);
291 return (instanceOop) result.get_oop();
292 }
293
294 objArrayHandle LiveFrameStream::values_to_object_array(StackValueCollection* values, TRAPS) {
295 objArrayHandle empty;
296 int length = values->size();
297 objArrayOop array_oop = oopFactory::new_objArray(vmClasses::Object_klass(),
298 length, CHECK_(empty));
299 objArrayHandle array_h(THREAD, array_oop);
300 for (int i = 0; i < values->size(); i++) {
301 StackValue* st = values->at(i);
302 BasicType type = st->type();
303 int index = i;
304 #ifdef _LP64
305 if (type != T_OBJECT && type != T_CONFLICT) {
306 intptr_t ret = st->get_intptr(); // read full 64-bit slot
307 type = T_LONG; // treat as long
308 index--; // undo +1 in StackValueCollection::long_at
309 }
310 #endif
311 oop obj = create_primitive_slot_instance(values, index, type, CHECK_(empty));
312 if (obj != nullptr) {
313 array_h->obj_at_put(i, obj);
314 }
315 }
316 return array_h;
317 }
318
319 objArrayHandle LiveFrameStream::monitors_to_object_array(GrowableArray<MonitorInfo*>* monitors, TRAPS) {
320 int length = monitors->length();
321 objArrayOop array_oop = oopFactory::new_objArray(vmClasses::Object_klass(),
322 length, CHECK_(objArrayHandle()));
323 objArrayHandle array_h(THREAD, array_oop);
324 for (int i = 0; i < length; i++) {
325 MonitorInfo* monitor = monitors->at(i);
326 array_h->obj_at_put(i, monitor->owner());
327 }
328 return array_h;
329 }
330
331 // Fill StackFrameInfo with bci and initialize ResolvedMethodName
332 void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) {
333 java_lang_StackFrameInfo::set_method_and_bci(stackFrame, method, bci(), cont(), THREAD);
334 }
335
336 // Fill LiveStackFrameInfo with locals, monitors, and expressions
337 void LiveFrameStream::fill_live_stackframe(Handle stackFrame,
338 const methodHandle& method, TRAPS) {
339 fill_stackframe(stackFrame, method, CHECK);
340 if (_jvf != nullptr) {
341 ResourceMark rm(THREAD);
342 HandleMark hm(THREAD);
343
344 StackValueCollection* locals = _jvf->locals();
345 StackValueCollection* expressions = _jvf->expressions();
346 GrowableArray<MonitorInfo*>* monitors = _jvf->monitors();
347
348 int mode = 0;
349 if (_jvf->is_interpreted_frame()) {
350 mode = MODE_INTERPRETED;
351 } else if (_jvf->is_compiled_frame()) {
352 mode = MODE_COMPILED;
353 }
354
355 if (!locals->is_empty()) {
356 objArrayHandle locals_h = values_to_object_array(locals, CHECK);
357 java_lang_LiveStackFrameInfo::set_locals(stackFrame(), locals_h());
358 }
359 if (!expressions->is_empty()) {
360 objArrayHandle expressions_h = values_to_object_array(expressions, CHECK);
361 java_lang_LiveStackFrameInfo::set_operands(stackFrame(), expressions_h());
362 }
363 if (monitors->length() > 0) {
364 objArrayHandle monitors_h = monitors_to_object_array(monitors, CHECK);
365 java_lang_LiveStackFrameInfo::set_monitors(stackFrame(), monitors_h());
366 }
367 java_lang_LiveStackFrameInfo::set_mode(stackFrame(), mode);
368 }
369 }
370
371 // Begins stack walking.
372 //
373 // Parameters:
374 // stackStream StackStream object
375 // mode Stack walking mode.
376 // skip_frames Number of frames to be skipped.
377 // cont_scope Continuation scope to walk (if not in this scope, we'll walk all the way).
378 // buffer_size Buffer size.
379 // start_index Start index to the user-supplied buffers.
380 // frames_array Buffer to store stack frame info in, starting at start_index.
381 // frames array is a ClassFrameInfo[] array when only getting caller
382 // reference, and a StackFrameInfo[] array (or derivative)
383 // otherwise. It should never be null.
384 //
385 // Returns Object returned from AbstractStackWalker::doStackWalk call.
386 //
387 oop StackWalk::walk(Handle stackStream, jint mode, int skip_frames, Handle cont_scope, Handle cont,
388 int buffer_size, int start_index, refArrayHandle frames_array,
389 TRAPS) {
390 ResourceMark rm(THREAD);
391 HandleMark hm(THREAD); // needed to store a continuation in the RegisterMap
392
393 JavaThread* jt = THREAD;
394 log_debug(stackwalk)("Start walking: mode " INT32_FORMAT_X " skip %d frames, buffer size %d", mode, skip_frames, buffer_size);
395 LogTarget(Debug, stackwalk) lt;
396 if (lt.is_enabled()) {
397 ResourceMark rm(THREAD);
398 LogStream ls(lt);
399 if (cont_scope() != nullptr) {
400 ls.print("cont_scope: ");
401 cont_scope()->print_on(&ls);
402 }
403 ls.cr();
404 }
405
406 if (frames_array.is_null()) {
407 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is null", nullptr);
408 }
409
410 // Setup traversal onto my stack.
411 if (live_frame_info(mode)) {
412 RegisterMap regMap = cont.is_null() ? RegisterMap(jt,
413 RegisterMap::UpdateMap::include,
414 RegisterMap::ProcessFrames::include,
415 RegisterMap::WalkContinuation::include)
416 : RegisterMap(cont(), RegisterMap::UpdateMap::include);
417 LiveFrameStream stream(jt, ®Map, cont_scope, cont);
418 return fetchFirstBatch(stream, stackStream, mode, skip_frames, buffer_size,
419 start_index, frames_array, THREAD);
420 } else {
421 JavaFrameStream stream(jt, mode, cont_scope, cont);
422 return fetchFirstBatch(stream, stackStream, mode, skip_frames, buffer_size,
423 start_index, frames_array, THREAD);
424 }
425 }
426
427 oop StackWalk::fetchFirstBatch(BaseFrameStream& stream, Handle stackStream,
428 jint mode, int skip_frames, int buffer_size,
429 int start_index, refArrayHandle frames_array, TRAPS) {
430 methodHandle m_doStackWalk(THREAD, Universe::do_stack_walk_method());
431
432 {
433 Klass* stackWalker_klass = vmClasses::StackWalker_klass();
434 Klass* abstractStackWalker_klass = vmClasses::AbstractStackWalker_klass();
435 while (!stream.at_end()) {
436 InstanceKlass* ik = stream.method()->method_holder();
437 if (ik != stackWalker_klass &&
438 ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) {
439 break;
440 }
441 log_debug(stackwalk)(" skip %s", stream.method()->external_name());
442 stream.next();
443 }
444
445 // stack frame has been traversed individually and resume stack walk
446 // from the stack frame at depth == skip_frames.
447 for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) {
448 log_debug(stackwalk)(" skip %s", stream.method()->external_name());
449 }
450 }
451
452 int end_index = start_index;
453 int numFrames = 0;
454 if (!stream.at_end()) {
455 KeepStackGCProcessedMark keep_stack(THREAD);
456 numFrames = fill_in_frames(mode, stream, buffer_size, start_index,
457 frames_array, end_index, CHECK_NULL);
458 if (numFrames < 1) {
459 THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", nullptr);
460 }
461 }
462
463 // JVM_CallStackWalk walks the stack and fills in stack frames, then calls to
464 // Java method java.lang.StackStreamFactory.AbstractStackWalker::doStackWalk
465 // which calls the implementation to consume the stack frames.
466 // When JVM_CallStackWalk returns, it invalidates the stack stream.
467 JavaValue result(T_OBJECT);
468 JavaCallArguments args(stackStream);
469 args.push_long(stream.address_value());
470 args.push_int(skip_frames);
471 args.push_int(numFrames);
472 args.push_int(start_index);
473 args.push_int(end_index);
474
475 // Link the thread and vframe stream into the callee-visible object
476 stream.setup_magic_on_entry(frames_array);
477
478 JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
479
480 // Do this before anything else happens, to disable any lingering stream objects
481 bool ok = stream.cleanup_magic_on_exit(frames_array);
482
483 // Throw pending exception if we must
484 (void) (CHECK_NULL);
485
486 if (!ok) {
487 THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers on exit", nullptr);
488 }
489
490 // Return normally
491 return result.get_oop();
492 }
493
494 // Walk the next batch of stack frames
495 //
496 // Parameters:
497 // stackStream StackStream object
498 // mode Stack walking mode.
499 // magic Must be valid value to continue the stack walk
500 // last_batch_count Number of frames fetched in the last batch.
501 // buffer_size Buffer size.
502 // start_index Start index to the user-supplied buffers.
503 // frames_array Buffer to store StackFrame in, starting at start_index.
504 //
505 // Returns the number of frames filled in the buffer.
506 //
507 jint StackWalk::fetchNextBatch(Handle stackStream, jint mode, jlong magic,
508 int last_batch_count, int buffer_size, int start_index,
509 refArrayHandle frames_array,
510 TRAPS)
511 {
512 JavaThread* jt = THREAD;
513 BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array);
514 if (existing_stream == nullptr) {
515 THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
516 }
517
518 if (frames_array.is_null()) {
519 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is null", 0L);
520 }
521
522 log_debug(stackwalk)("StackWalk::fetchNextBatch last_batch_count %d buffer_size %d existing_stream "
523 PTR_FORMAT " start %d", last_batch_count,
524 buffer_size, p2i(existing_stream), start_index);
525 int end_index = start_index;
526 if (buffer_size <= start_index) {
527 return 0; // No operation.
528 }
529
530 assert (frames_array->length() >= buffer_size, "frames_array length < buffer_size");
531
532 BaseFrameStream& stream = (*existing_stream);
533 if (!stream.at_end()) {
534 // If we have to get back here for even more frames, then 1) the user did not supply
535 // an accurate hint suggesting the depth of the stack walk, and 2) we are not just
536 // peeking at a few frames. Take the cost of flushing out any pending deferred GC
537 // processing of the stack.
538 KeepStackGCProcessedMark keep_stack(jt);
539
540 // Advance past the last frame decoded in the previous batch.
541 // If the last batch is empty, it means that the last batch returns after
542 // it advanced the frame it previously decoded as it reaches the bottom of
543 // the continuation and it returns to let Java side set the continuation.
544 // Now this batch starts right at the first frame of another continuation.
545 if (last_batch_count > 0) {
546 // It is not always safe to dig out the name of the last frame
547 // here, i.e. stream.method()->external_name(), since it may
548 // have been reclaimed by HandleMark::pop_and_restore() together
549 // with the rest of the previous batch.
550 log_debug(stackwalk)("advanced past last frame decoded in the previous batch");
551 stream.next();
552 }
553
554 if (!stream.at_end()) {
555 int numFrames = fill_in_frames(mode, stream, buffer_size, start_index,
556 frames_array, end_index, CHECK_0);
557 if (numFrames < 1 && !skip_hidden_frames(mode)) {
558 THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
559 }
560 return numFrames;
561 }
562 }
563 return 0;
564 }
565
566 void StackWalk::setContinuation(Handle stackStream, jlong magic, refArrayHandle frames_array, Handle cont, TRAPS) {
567 JavaThread* jt = JavaThread::cast(THREAD);
568
569 if (frames_array.is_null()) {
570 THROW_MSG(vmSymbols::java_lang_NullPointerException(), "frames_array is null");
571 }
572
573 BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array);
574 if (existing_stream == nullptr) {
575 THROW_MSG(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers");
576 }
577
578 existing_stream->set_continuation(cont);
579 }