Skip to content

Commit

Permalink
Merge branch 'master' into 8345322
Browse files Browse the repository at this point in the history
  • Loading branch information
robehn committed Dec 13, 2024
2 parents 5b91eea + 31ceec7 commit 2705301
Show file tree
Hide file tree
Showing 56 changed files with 1,218 additions and 453 deletions.
4 changes: 2 additions & 2 deletions src/hotspot/cpu/zero/frame_zero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ bool frame::safe_for_sender(JavaThread *thread) {
bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
assert(is_interpreted_frame(), "Not an interpreted frame");
// These are reasonable sanity checks
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
if (fp() == nullptr || (intptr_t(fp()) & (wordSize-1)) != 0) {
return false;
}
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
if (sp() == nullptr || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false;
}
// These are hacks to keep us out of trouble.
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ HeapWord* ShenandoahFreeSet::allocate_single(ShenandoahAllocRequest& req, bool&
// Free set maintains mutator and collector partitions. Normally, each allocates only from its partition,
// except in special cases when the collector steals regions from the mutator partition.

// Overwrite with non-zero (non-NULL) values only if necessary for allocation bookkeeping.
// Overwrite with non-zero (non-null) values only if necessary for allocation bookkeeping.

switch (req.type()) {
case ShenandoahAllocRequest::_alloc_tlab:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ void ShenandoahGenerationalEvacuationTask::promote_in_place(ShenandoahHeapRegion
while (obj_addr < tams) {
oop obj = cast_to_oop(obj_addr);
if (marking_context->is_marked(obj)) {
assert(obj->klass() != nullptr, "klass should not be NULL");
assert(obj->klass() != nullptr, "klass should not be null");
// This thread is responsible for registering all objects in this region. No need for lock.
scanner->register_object_without_lock(obj_addr);
obj_addr += obj->size();
Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/share/gc/z/zUtils.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -25,8 +25,6 @@
#include "gc/z/zUtils.hpp"
#include "runtime/nonJavaThread.hpp"

#include <algorithm>

const char* ZUtils::thread_name() {
const Thread* const thread = Thread::current();
if (thread->is_Named_thread()) {
Expand All @@ -38,5 +36,7 @@ const char* ZUtils::thread_name() {
}

void ZUtils::fill(uintptr_t* addr, size_t count, uintptr_t value) {
std::fill_n(addr, count, value);
for (size_t i = 0; i < count; ++i) {
addr[i] = value;
}
}
14 changes: 5 additions & 9 deletions src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#include "utilities/stringUtils.hpp"
#include "utilities/nativeStackPrinter.hpp"
#include "utilities/pair.hpp"
#include "utilities/stringUtils.hpp"
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
#endif
Expand Down Expand Up @@ -4009,14 +4010,9 @@ void InstanceKlass::print_class_load_cause_logging() const {
stringStream stack_stream;
char buf[O_BUFLEN];
address lastpc = nullptr;
if (os::platform_print_native_stack(&stack_stream, nullptr, buf, O_BUFLEN, lastpc)) {
// We have printed the native stack in platform-specific code,
// so nothing else to do in this case.
} else {
frame f = os::current_frame();
VMError::print_native_stack(&stack_stream, f, current, true /*print_source_info */,
-1 /* max stack_stream */, buf, O_BUFLEN);
}
NativeStackPrinter nsp(current);
nsp.print_stack(&stack_stream, buf, sizeof(buf), lastpc,
true /* print_source_info */, -1 /* max stack */);

LogMessage(class, load, cause, native) msg;
NonInterleavingLogStream info_stream{LogLevelType::Info, msg};
Expand Down
33 changes: 33 additions & 0 deletions src/hotspot/share/runtime/frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,39 @@ void frame::describe(FrameValues& values, int frame_no, const RegisterMap* reg_m

#endif

/**
* Gets the caller frame of `fr` for thread `t`.
*
* @returns an invalid frame (i.e. fr.pc() === 0) if the caller cannot be obtained
*/
frame frame::next_frame(frame fr, Thread* t) {
// Compiled code may use EBP register on x86 so it looks like
// non-walkable C frame. Use frame.sender() for java frames.
frame invalid;
if (t != nullptr && t->is_Java_thread()) {
// Catch very first native frame by using stack address.
// For JavaThread stack_base and stack_size should be set.
if (!t->is_in_full_stack((address)(fr.real_fp() + 1))) {
return invalid;
}
if (fr.is_interpreted_frame() || (fr.cb() != nullptr && fr.cb()->frame_size() > 0)) {
RegisterMap map(JavaThread::cast(t),
RegisterMap::UpdateMap::skip,
RegisterMap::ProcessFrames::include,
RegisterMap::WalkContinuation::skip); // No update
return fr.sender(&map);
} else {
// is_first_C_frame() does only simple checks for frame pointer,
// it will pass if java compiled code has a pointer in EBP.
if (os::is_first_C_frame(&fr)) return invalid;
return os::get_sender_for_C_frame(&fr);
}
} else {
if (os::is_first_C_frame(&fr)) return invalid;
return os::get_sender_for_C_frame(&fr);
}
}

#ifndef PRODUCT

void FrameValues::describe(int owner, intptr_t* location, const char* description, int priority) {
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/runtime/frame.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ class frame {
void interpreter_frame_print_on(outputStream* st) const;
void print_on_error(outputStream* st, char* buf, int buflen, bool verbose = false) const;
static void print_C_frame(outputStream* st, char* buf, int buflen, address pc);
static frame next_frame(frame fr, Thread* t); // For native stack walking

#ifndef PRODUCT
// Add annotated descriptions of memory locations belonging to this frame to values
Expand Down
12 changes: 4 additions & 8 deletions src/hotspot/share/runtime/javaThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#include "utilities/nativeStackPrinter.hpp"
#include "utilities/preserveException.hpp"
#include "utilities/spinYield.hpp"
#include "utilities/vmError.hpp"
Expand Down Expand Up @@ -1772,15 +1773,10 @@ void JavaThread::print_jni_stack() {
tty->print_cr("Unable to print native stack - out of memory");
return;
}
NativeStackPrinter nsp(this);
address lastpc = nullptr;
if (os::platform_print_native_stack(tty, nullptr, buf, O_BUFLEN, lastpc)) {
// We have printed the native stack in platform-specific code,
// so nothing else to do in this case.
} else {
frame f = os::current_frame();
VMError::print_native_stack(tty, f, this, true /*print_source_info */,
-1 /* max stack */, buf, O_BUFLEN);
}
nsp.print_stack(tty, buf, O_BUFLEN, lastpc,
true /*print_source_info */, -1 /* max stack */ );
} else {
print_active_stack_on(tty);
}
Expand Down
17 changes: 7 additions & 10 deletions src/hotspot/share/utilities/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include "utilities/formatBuffer.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include "utilities/nativeStackPrinter.hpp"
#include "utilities/unsigned5.hpp"
#include "utilities/vmError.hpp"

Expand Down Expand Up @@ -645,10 +646,11 @@ void help() {
extern "C" DEBUGEXPORT void pns(void* sp, void* fp, void* pc) { // print native stack
Command c("pns");
static char buf[O_BUFLEN];
Thread* t = Thread::current_or_null();
// Call generic frame constructor (certain arguments may be ignored)
frame fr(sp, fp, pc);
VMError::print_native_stack(tty, fr, t, false, -1, buf, sizeof(buf));
NativeStackPrinter nsp(Thread::current_or_null());
nsp.print_stack_from_frame(tty, fr, buf, sizeof(buf),
false /* print_source_info */, -1 /* max stack */);
}

//
Expand All @@ -663,14 +665,9 @@ extern "C" DEBUGEXPORT void pns2() { // print native stack
Command c("pns2");
static char buf[O_BUFLEN];
address lastpc = nullptr;
if (os::platform_print_native_stack(tty, nullptr, buf, sizeof(buf), lastpc)) {
// We have printed the native stack in platform-specific code,
// so nothing else to do in this case.
} else {
Thread* t = Thread::current_or_null();
frame fr = os::current_frame();
VMError::print_native_stack(tty, fr, t, false, -1, buf, sizeof(buf));
}
NativeStackPrinter nsp(Thread::current_or_null());
nsp.print_stack(tty, buf, sizeof(buf), lastpc,
false /* print_source_info */, -1 /* max stack */);
}
#endif

Expand Down
81 changes: 81 additions & 0 deletions src/hotspot/share/utilities/nativeStackPrinter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/

#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/os.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/nativeStackPrinter.hpp"
#include "utilities/ostream.hpp"

bool NativeStackPrinter::print_stack(outputStream* st, char* buf, int buf_size,
address& lastpc, bool print_source_info,
int max_frames) {
if (os::platform_print_native_stack(st, _context, buf, buf_size, lastpc)) {
return true;
} else {
print_stack_from_frame(st, buf, buf_size, print_source_info, max_frames);
return false;
}
}

void NativeStackPrinter::print_stack_from_frame(outputStream* st, frame fr,
char* buf, int buf_size,
bool print_source_info, int max_frames) {
// see if it's a valid frame
if (fr.pc()) {
st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
const int limit = max_frames == -1 ? StackPrintLimit
: MIN2(max_frames, StackPrintLimit);
int count = 0;
while (count++ < limit) {
fr.print_on_error(st, buf, buf_size);
if (fr.pc()) { // print source file and line, if available
char filename[128];
int line_no;
if (count == 1 && _lineno != 0) {
// We have source information for the first frame for internal errors,
// there is no need to parse it from the symbols.
st->print(" (%s:%d)", _filename, _lineno);
} else if (print_source_info &&
Decoder::get_source_info(fr.pc(), filename, sizeof(filename), &line_no, count != 1)) {
st->print(" (%s:%d)", filename, line_no);
}
}
st->cr();
fr = frame::next_frame(fr, _current);
if (fr.pc() == nullptr) {
break;
}
}

if (count > limit) {
st->print_cr("...<more frames>...");
}

} else {
st->print_cr("Native frames: <unavailable>");
}
}
108 changes: 108 additions & 0 deletions src/hotspot/share/utilities/nativeStackPrinter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_UTILITIES_NATIVESTACKPRINTER_HPP
#define SHARE_UTILITIES_NATIVESTACKPRINTER_HPP

#include "memory/allocation.hpp"
#include "runtime/frame.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"

// Forward declarations
class outputStream;
class Thread;

// Helper class to do native stack printing from various contexts
// including during crash reporting.
// The NativeStackPrinter is created with the basic context information
// available from the caller. Then the print_stack function is called
// to do the actual printing.
class NativeStackPrinter : public StackObj {
Thread* _current; // Current thread if known
const void* _context; // OS crash context if known
const char* _filename; // Source file name if known
int _lineno; // Source file line number if known

public:
// Creates a NativeStackPrinter using the given additional context
// information:
// - the current thread is used for frame-based stack walking
// - context is the crash context from the OS and can be used to get a frame;
// otherwise os::current_frame() will be used
// - filename and lineno provide details from the fatal error handler so we
// can skip use of the Decoder for the first line (optimization)
NativeStackPrinter(Thread* current_or_null,
const void* context,
const char* filename,
int lineno) :
_current(current_or_null),
_context(context),
_filename(filename),
_lineno(lineno) {
assert((_lineno == 0 && _filename == nullptr) ||
(_lineno > 0 && _filename != nullptr),
"file name and line number need to be provided together");
}

NativeStackPrinter(Thread* current_or_null)
: NativeStackPrinter(current_or_null, nullptr, nullptr, 0) {}

// Prints the stack of the current thread to the given stream.
// We first try to print via os::platform_print_native_stack. If that
// succeeds then lastpc is set and we return true. Otherwise we do a
// frame walk to print the stack, and return false.
// - st: the stream to print to
// - buf, buf_size: temporary buffer to use for formatting output
// - print_source_info: see print_stack_from_frame
// - max_frames: see print_stack_from_frame
//
bool print_stack(outputStream* st, char* buf, int buf_size,
address& lastpc, bool print_source_info,
int max_frames);

// Prints the stack to st by walking the frames starting from
// either the context frame, else the current frame.
// - st: the stream to print to
// - buf, buf_size: temporary buffer to use when printing frames
// - print_source_info: if true obtains source information from the Decoder
// if available. (Useful but may slow down, timeout or
// misfunction in error situations)
// - max_frames: the maximum number of frames to print. -1 means print all.
// However, StackPrintLimit sets a hard limit on the maximum.
void print_stack_from_frame(outputStream* st, frame fr,
char* buf, int buf_size,
bool print_source_info, int max_frames);

// Prints the stack to st by walking the frames starting from
// either the context frame, else the current frame.
void print_stack_from_frame(outputStream* st,
char* buf, int buf_size,
bool print_source_info, int max_frames) {
frame fr = _context != nullptr ? os::fetch_frame_from_context(_context)
: os::current_frame();
print_stack_from_frame(st, fr, buf, buf_size, print_source_info, max_frames);
}
};

#endif // SHARE_UTILITIES_NATIVESTACKPRINTER_HPP
Loading

0 comments on commit 2705301

Please sign in to comment.