summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/instrumentation.cc37
-rw-r--r--runtime/instrumentation.h4
-rw-r--r--runtime/quick_exception_handler.cc6
-rw-r--r--runtime/trace.cc2
-rw-r--r--test/2246-trace-stream/expected-stdout.debuggable.txt72
-rw-r--r--test/2246-trace-stream/expected-stdout.interpreter.txt68
-rw-r--r--test/2246-trace-stream/expected-stdout.txt99
-rw-r--r--test/2246-trace-stream/run.py14
-rw-r--r--test/2246-trace-stream/src/Main.java14
9 files changed, 249 insertions, 67 deletions
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 13c2b57821..104c46532b 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -457,6 +457,30 @@ void Instrumentation::UpdateEntrypointsForDebuggable() {
runtime->GetClassLinker()->VisitClasses(&visitor);
}
+bool Instrumentation::MethodSupportsExitEvents(ArtMethod* method,
+ const OatQuickMethodHeader* header) {
+ if (header == nullptr) {
+ // Header can be a nullptr for runtime / proxy methods that doesn't support method exit hooks
+ // or for native methods that use generic jni stubs. Generic jni stubs support method exit
+ // hooks.
+ return method->IsNative();
+ }
+
+ if (header->IsNterpMethodHeader()) {
+ // Nterp doesn't support method exit events
+ return false;
+ }
+
+ DCHECK(header->IsOptimized());
+ if (CodeInfo::IsDebuggable(header->GetOptimizedCodeInfoPtr())) {
+ // For optimized code, we only support method entry / exit hooks if they are compiled as
+ // debuggable.
+ return true;
+ }
+
+ return false;
+}
+
// Places the instrumentation exit pc as the return PC for every quick frame. This also allows
// deoptimization of quick frames to interpreter frames. When force_deopt is
// true the frames have to be deoptimized. If the frame has a deoptimization
@@ -508,9 +532,15 @@ void InstrumentationInstallStack(Thread* thread, void* arg, bool deopt_all_frame
LOG(INFO) << " Processing quick frame for updating exit hooks " << DescribeLocation();
}
- // Record the method so we can call method entry callbacks for all non-runtime methods on
- // the stack. Runtime methods don't need method entry callbacks.
- stack_methods_.push_back(m);
+ const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
+ if (Runtime::Current()->GetInstrumentation()->MethodSupportsExitEvents(m, method_header)) {
+ // It is unexpected to see a method enter event but not a method exit event so record stack
+ // methods only for frames that support method exit events. Even if we deoptimize we make
+ // sure that we only call method exit event if the frame supported it in the first place.
+ // For ex: deoptimizing from JITed code with debug support calls a method exit hook but
+ // deoptimizing from nterp doesn't.
+ stack_methods_.push_back(m);
+ }
// If it is a JITed frame then just set the deopt bit if required otherwise continue.
// We need kForceDeoptForRedefinition to ensure we don't use any JITed code after a
@@ -519,7 +549,6 @@ void InstrumentationInstallStack(Thread* thread, void* arg, bool deopt_all_frame
// The CheckCallerForDeopt is an optimization which we only do for non-native JITed code for
// now. We can extend it to native methods but that needs reserving an additional stack slot.
// We don't do it currently since that wasn't important for debugger performance.
- const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
if (method_header != nullptr && method_header->HasShouldDeoptimizeFlag()) {
if (deopt_all_frames_) {
runtime_methods_need_deopt_check_ = true;
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 390d84a87a..aecad1f6e6 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -47,6 +47,7 @@ template <typename T> class Handle;
template <typename T> class MutableHandle;
struct NthCallerVisitor;
union JValue;
+class OatQuickMethodHeader;
class SHARED_LOCKABLE ReaderWriterMutex;
class ShadowFrame;
class Thread;
@@ -603,6 +604,9 @@ class Instrumentation {
InstrumentationLevel GetCurrentInstrumentationLevel() const;
+ bool MethodSupportsExitEvents(ArtMethod* method, const OatQuickMethodHeader* header)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
private:
// Returns true if moving to the given instrumentation level requires the installation of stubs.
// False otherwise.
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index eb9b47180f..1dc90097e0 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -476,6 +476,12 @@ class DeoptimizeStackVisitor final : public StackVisitor {
} else {
HandleOptimizingDeoptimization(method, new_frame, updated_vregs);
}
+ // Update if method exit event needs to be reported. We should report exit event only if we
+ // have reported an entry event. So tell interpreter if/ an entry event was reported.
+ bool supports_exit_events =
+ Runtime::Current()->GetInstrumentation()->MethodSupportsExitEvents(
+ method, GetCurrentOatQuickMethodHeader());
+ new_frame->SetSkipMethodExitEvents(!supports_exit_events);
if (updated_vregs != nullptr) {
// Calling Thread::RemoveDebuggerShadowFrameMapping will also delete the updated_vregs
// array so this must come after we processed the frame.
diff --git a/runtime/trace.cc b/runtime/trace.cc
index eb0c04eb03..387816fa03 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -424,6 +424,8 @@ void Trace::Start(std::unique_ptr<File>&& trace_file_in,
jit->GetJitCompiler()->SetDebuggableCompilerOption(true);
}
runtime->SetRuntimeDebugState(art::Runtime::RuntimeDebugState::kJavaDebuggable);
+ runtime->GetInstrumentation()->UpdateEntrypointsForDebuggable();
+ runtime->DeoptimizeBootImage();
}
runtime->GetInstrumentation()->AddListener(
the_trace_,
diff --git a/test/2246-trace-stream/expected-stdout.debuggable.txt b/test/2246-trace-stream/expected-stdout.debuggable.txt
new file mode 100644
index 0000000000..c9d7405c8b
--- /dev/null
+++ b/test/2246-trace-stream/expected-stdout.debuggable.txt
@@ -0,0 +1,72 @@
+.>> TestThread2246 java.lang.Thread run ()V Thread.java
+..>> TestThread2246 Main$$ExternalSyntheticLambda0 run ()V D8$$SyntheticClass
+...>> TestThread2246 Main lambda$main$0 ()V Main.java
+....>> TestThread2246 Main <init> ()V Main.java
+.....>> TestThread2246 java.lang.Object <init> ()V Object.java
+.....<< TestThread2246 java.lang.Object <init> ()V Object.java
+....<< TestThread2246 Main <init> ()V Main.java
+....>> TestThread2246 Main $noinline$doSomeWork ()V Main.java
+.....>> TestThread2246 Main callOuterFunction ()V Main.java
+......>> TestThread2246 Main callLeafFunction ()V Main.java
+......<< TestThread2246 Main callLeafFunction ()V Main.java
+.....<< TestThread2246 Main callOuterFunction ()V Main.java
+.....>> TestThread2246 Main callLeafFunction ()V Main.java
+.....<< TestThread2246 Main callLeafFunction ()V Main.java
+....<< TestThread2246 Main $noinline$doSomeWork ()V Main.java
+...<< TestThread2246 Main lambda$main$0 ()V Main.java
+..<< TestThread2246 Main$$ExternalSyntheticLambda0 run ()V D8$$SyntheticClass
+.<< TestThread2246 java.lang.Thread run ()V Thread.java
+.>> main Main main ([Ljava/lang/String;)V Main.java
+..>> main Main$VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V Main.java
+...>> main java.lang.reflect.Method invoke (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; Method.java
+....>> main dalvik.system.VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V VMDebug.java
+.....>> main dalvik.system.VMDebug startMethodTracingFd (Ljava/lang/String;IIIZIZ)V VMDebug.java
+.....<< main dalvik.system.VMDebug startMethodTracingFd (Ljava/lang/String;IIIZIZ)V VMDebug.java
+....<< main dalvik.system.VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V VMDebug.java
+...<< main java.lang.reflect.Method invoke (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; Method.java
+..<< main Main$VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V Main.java
+..>> main java.lang.Thread start ()V Thread.java
+...>> main java.lang.ThreadGroup add (Ljava/lang/Thread;)V ThreadGroup.java
+...<< main java.lang.ThreadGroup add (Ljava/lang/Thread;)V ThreadGroup.java
+...>> main java.lang.Thread nativeCreate (Ljava/lang/Thread;JZ)V Thread.java
+...<< main java.lang.Thread nativeCreate (Ljava/lang/Thread;JZ)V Thread.java
+..<< main java.lang.Thread start ()V Thread.java
+..>> main java.lang.Thread join ()V Thread.java
+...>> main java.lang.Thread join (J)V Thread.java
+....>> main java.lang.System currentTimeMillis ()J System.java
+....<< main java.lang.System currentTimeMillis ()J System.java
+....>> main java.lang.Thread isAlive ()Z Thread.java
+....<< main java.lang.Thread isAlive ()Z Thread.java
+....>> main java.lang.Object wait (J)V Object.java
+.....>> main java.lang.Object wait (JI)V Object.java
+.....<< main java.lang.Object wait (JI)V Object.java
+....<< main java.lang.Object wait (J)V Object.java
+....>> main java.lang.Thread isAlive ()Z Thread.java
+....<< main java.lang.Thread isAlive ()Z Thread.java
+...<< main java.lang.Thread join (J)V Thread.java
+..<< main java.lang.Thread join ()V Thread.java
+..>> main Main $noinline$doSomeWork ()V Main.java
+...>> main Main callOuterFunction ()V Main.java
+....>> main Main callLeafFunction ()V Main.java
+....<< main Main callLeafFunction ()V Main.java
+...<< main Main callOuterFunction ()V Main.java
+...>> main Main callLeafFunction ()V Main.java
+...<< main Main callLeafFunction ()V Main.java
+..<< main Main $noinline$doSomeWork ()V Main.java
+..>> main Main doSomeWorkThrow ()V Main.java
+...>> main Main callThrowFunction ()V Main.java
+....>> main java.lang.Exception <init> (Ljava/lang/String;)V Exception.java
+.....>> main java.lang.Throwable <init> (Ljava/lang/String;)V Throwable.java
+......>> main java.lang.Object <init> ()V Object.java
+......<< main java.lang.Object <init> ()V Object.java
+......>> main java.util.Collections emptyList ()Ljava/util/List; Collections.java
+......<< main java.util.Collections emptyList ()Ljava/util/List; Collections.java
+......>> main java.lang.Throwable fillInStackTrace ()Ljava/lang/Throwable; Throwable.java
+.......>> main java.lang.Throwable nativeFillInStackTrace ()Ljava/lang/Object; Throwable.java
+.......<< main java.lang.Throwable nativeFillInStackTrace ()Ljava/lang/Object; Throwable.java
+......<< main java.lang.Throwable fillInStackTrace ()Ljava/lang/Throwable; Throwable.java
+.....<< main java.lang.Throwable <init> (Ljava/lang/String;)V Throwable.java
+....<< main java.lang.Exception <init> (Ljava/lang/String;)V Exception.java
+...<<E main Main callThrowFunction ()V Main.java
+..<< main Main doSomeWorkThrow ()V Main.java
+..>> main Main$VMDebug $noinline$stopMethodTracing ()V Main.java
diff --git a/test/2246-trace-stream/expected-stdout.interpreter.txt b/test/2246-trace-stream/expected-stdout.interpreter.txt
new file mode 100644
index 0000000000..c51ce41de7
--- /dev/null
+++ b/test/2246-trace-stream/expected-stdout.interpreter.txt
@@ -0,0 +1,68 @@
+.>> TestThread2246 java.lang.Thread run ()V Thread.java
+..>> TestThread2246 Main$$ExternalSyntheticLambda0 run ()V D8$$SyntheticClass
+...>> TestThread2246 Main lambda$main$0 ()V Main.java
+....>> TestThread2246 Main <init> ()V Main.java
+.....>> TestThread2246 java.lang.Object <init> ()V Object.java
+.....<< TestThread2246 java.lang.Object <init> ()V Object.java
+....<< TestThread2246 Main <init> ()V Main.java
+....>> TestThread2246 Main $noinline$doSomeWork ()V Main.java
+.....>> TestThread2246 Main callOuterFunction ()V Main.java
+......>> TestThread2246 Main callLeafFunction ()V Main.java
+......<< TestThread2246 Main callLeafFunction ()V Main.java
+.....<< TestThread2246 Main callOuterFunction ()V Main.java
+.....>> TestThread2246 Main callLeafFunction ()V Main.java
+.....<< TestThread2246 Main callLeafFunction ()V Main.java
+....<< TestThread2246 Main $noinline$doSomeWork ()V Main.java
+...<< TestThread2246 Main lambda$main$0 ()V Main.java
+..<< TestThread2246 Main$$ExternalSyntheticLambda0 run ()V D8$$SyntheticClass
+.<< TestThread2246 java.lang.Thread run ()V Thread.java
+.>> main Main main ([Ljava/lang/String;)V Main.java
+..>> main Main$VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V Main.java
+...>> main dalvik.system.VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V VMDebug.java
+...<< main dalvik.system.VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V VMDebug.java
+..<< main Main$VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V Main.java
+..>> main java.lang.Thread start ()V Thread.java
+...>> main java.lang.ThreadGroup add (Ljava/lang/Thread;)V ThreadGroup.java
+...<< main java.lang.ThreadGroup add (Ljava/lang/Thread;)V ThreadGroup.java
+...>> main java.lang.Thread nativeCreate (Ljava/lang/Thread;JZ)V Thread.java
+...<< main java.lang.Thread nativeCreate (Ljava/lang/Thread;JZ)V Thread.java
+..<< main java.lang.Thread start ()V Thread.java
+..>> main java.lang.Thread join ()V Thread.java
+...>> main java.lang.Thread join (J)V Thread.java
+....>> main java.lang.System currentTimeMillis ()J System.java
+....<< main java.lang.System currentTimeMillis ()J System.java
+....>> main java.lang.Thread isAlive ()Z Thread.java
+....<< main java.lang.Thread isAlive ()Z Thread.java
+....>> main java.lang.Object wait (J)V Object.java
+.....>> main java.lang.Object wait (JI)V Object.java
+.....<< main java.lang.Object wait (JI)V Object.java
+....<< main java.lang.Object wait (J)V Object.java
+....>> main java.lang.Thread isAlive ()Z Thread.java
+....<< main java.lang.Thread isAlive ()Z Thread.java
+...<< main java.lang.Thread join (J)V Thread.java
+..<< main java.lang.Thread join ()V Thread.java
+..>> main Main $noinline$doSomeWork ()V Main.java
+...>> main Main callOuterFunction ()V Main.java
+....>> main Main callLeafFunction ()V Main.java
+....<< main Main callLeafFunction ()V Main.java
+...<< main Main callOuterFunction ()V Main.java
+...>> main Main callLeafFunction ()V Main.java
+...<< main Main callLeafFunction ()V Main.java
+..<< main Main $noinline$doSomeWork ()V Main.java
+..>> main Main doSomeWorkThrow ()V Main.java
+...>> main Main callThrowFunction ()V Main.java
+....>> main java.lang.Exception <init> (Ljava/lang/String;)V Exception.java
+.....>> main java.lang.Throwable <init> (Ljava/lang/String;)V Throwable.java
+......>> main java.lang.Object <init> ()V Object.java
+......<< main java.lang.Object <init> ()V Object.java
+......>> main java.util.Collections emptyList ()Ljava/util/List; Collections.java
+......<< main java.util.Collections emptyList ()Ljava/util/List; Collections.java
+......>> main java.lang.Throwable fillInStackTrace ()Ljava/lang/Throwable; Throwable.java
+.......>> main java.lang.Throwable nativeFillInStackTrace ()Ljava/lang/Object; Throwable.java
+.......<< main java.lang.Throwable nativeFillInStackTrace ()Ljava/lang/Object; Throwable.java
+......<< main java.lang.Throwable fillInStackTrace ()Ljava/lang/Throwable; Throwable.java
+.....<< main java.lang.Throwable <init> (Ljava/lang/String;)V Throwable.java
+....<< main java.lang.Exception <init> (Ljava/lang/String;)V Exception.java
+...<<E main Main callThrowFunction ()V Main.java
+..<< main Main doSomeWorkThrow ()V Main.java
+..>> main Main$VMDebug $noinline$stopMethodTracing ()V Main.java
diff --git a/test/2246-trace-stream/expected-stdout.txt b/test/2246-trace-stream/expected-stdout.txt
index 0ee77f61d3..76d68f85c5 100644
--- a/test/2246-trace-stream/expected-stdout.txt
+++ b/test/2246-trace-stream/expected-stdout.txt
@@ -5,68 +5,59 @@
.....>> TestThread2246 java.lang.Object <init> ()V Object.java
.....<< TestThread2246 java.lang.Object <init> ()V Object.java
....<< TestThread2246 Main <init> ()V Main.java
-....>> TestThread2246 Main doSomeWork ()V Main.java
+....>> TestThread2246 Main $noinline$doSomeWork ()V Main.java
.....>> TestThread2246 Main callOuterFunction ()V Main.java
......>> TestThread2246 Main callLeafFunction ()V Main.java
......<< TestThread2246 Main callLeafFunction ()V Main.java
.....<< TestThread2246 Main callOuterFunction ()V Main.java
.....>> TestThread2246 Main callLeafFunction ()V Main.java
.....<< TestThread2246 Main callLeafFunction ()V Main.java
-....<< TestThread2246 Main doSomeWork ()V Main.java
+....<< TestThread2246 Main $noinline$doSomeWork ()V Main.java
...<< TestThread2246 Main lambda$main$0 ()V Main.java
..<< TestThread2246 Main$$ExternalSyntheticLambda0 run ()V D8$$SyntheticClass
.<< TestThread2246 java.lang.Thread run ()V Thread.java
-.>> main Main main ([Ljava/lang/String;)V Main.java
-..>> main Main$VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V Main.java
-...>> main java.lang.reflect.Method invoke (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; Method.java
-....>> main dalvik.system.VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V VMDebug.java
-.....>> main dalvik.system.VMDebug startMethodTracingFd (Ljava/lang/String;IIIZIZ)V VMDebug.java
-.....<< main dalvik.system.VMDebug startMethodTracingFd (Ljava/lang/String;IIIZIZ)V VMDebug.java
-....<< main dalvik.system.VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V VMDebug.java
-...<< main java.lang.reflect.Method invoke (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; Method.java
-..<< main Main$VMDebug startMethodTracing (Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V Main.java
-..>> main java.lang.Thread start ()V Thread.java
-...>> main java.lang.ThreadGroup add (Ljava/lang/Thread;)V ThreadGroup.java
-...<< main java.lang.ThreadGroup add (Ljava/lang/Thread;)V ThreadGroup.java
-...>> main java.lang.Thread nativeCreate (Ljava/lang/Thread;JZ)V Thread.java
-...<< main java.lang.Thread nativeCreate (Ljava/lang/Thread;JZ)V Thread.java
-..<< main java.lang.Thread start ()V Thread.java
-..>> main java.lang.Thread join ()V Thread.java
-...>> main java.lang.Thread join (J)V Thread.java
-....>> main java.lang.System currentTimeMillis ()J System.java
-....<< main java.lang.System currentTimeMillis ()J System.java
-....>> main java.lang.Thread isAlive ()Z Thread.java
-....<< main java.lang.Thread isAlive ()Z Thread.java
-....>> main java.lang.Object wait (J)V Object.java
-.....>> main java.lang.Object wait (JI)V Object.java
-.....<< main java.lang.Object wait (JI)V Object.java
-....<< main java.lang.Object wait (J)V Object.java
-....>> main java.lang.Thread isAlive ()Z Thread.java
-....<< main java.lang.Thread isAlive ()Z Thread.java
-...<< main java.lang.Thread join (J)V Thread.java
-..<< main java.lang.Thread join ()V Thread.java
-..>> main Main doSomeWork ()V Main.java
-...>> main Main callOuterFunction ()V Main.java
-....>> main Main callLeafFunction ()V Main.java
-....<< main Main callLeafFunction ()V Main.java
-...<< main Main callOuterFunction ()V Main.java
+.>> main java.lang.Thread start ()V Thread.java
+..>> main java.lang.ThreadGroup add (Ljava/lang/Thread;)V ThreadGroup.java
+..<< main java.lang.ThreadGroup add (Ljava/lang/Thread;)V ThreadGroup.java
+..>> main java.lang.Thread nativeCreate (Ljava/lang/Thread;JZ)V Thread.java
+..<< main java.lang.Thread nativeCreate (Ljava/lang/Thread;JZ)V Thread.java
+.<< main java.lang.Thread start ()V Thread.java
+.>> main java.lang.Thread join ()V Thread.java
+..>> main java.lang.Thread join (J)V Thread.java
+...>> main java.lang.System currentTimeMillis ()J System.java
+...<< main java.lang.System currentTimeMillis ()J System.java
+...>> main java.lang.Thread isAlive ()Z Thread.java
+...<< main java.lang.Thread isAlive ()Z Thread.java
+...>> main java.lang.Object wait (J)V Object.java
+....>> main java.lang.Object wait (JI)V Object.java
+....<< main java.lang.Object wait (JI)V Object.java
+...<< main java.lang.Object wait (J)V Object.java
+...>> main java.lang.Thread isAlive ()Z Thread.java
+...<< main java.lang.Thread isAlive ()Z Thread.java
+..<< main java.lang.Thread join (J)V Thread.java
+.<< main java.lang.Thread join ()V Thread.java
+.>> main Main $noinline$doSomeWork ()V Main.java
+..>> main Main callOuterFunction ()V Main.java
...>> main Main callLeafFunction ()V Main.java
...<< main Main callLeafFunction ()V Main.java
-..<< main Main doSomeWork ()V Main.java
-..>> main Main doSomeWorkThrow ()V Main.java
-...>> main Main callThrowFunction ()V Main.java
-....>> main java.lang.Exception <init> (Ljava/lang/String;)V Exception.java
-.....>> main java.lang.Throwable <init> (Ljava/lang/String;)V Throwable.java
-......>> main java.lang.Object <init> ()V Object.java
-......<< main java.lang.Object <init> ()V Object.java
-......>> main java.util.Collections emptyList ()Ljava/util/List; Collections.java
-......<< main java.util.Collections emptyList ()Ljava/util/List; Collections.java
-......>> main java.lang.Throwable fillInStackTrace ()Ljava/lang/Throwable; Throwable.java
-.......>> main java.lang.Throwable nativeFillInStackTrace ()Ljava/lang/Object; Throwable.java
-.......<< main java.lang.Throwable nativeFillInStackTrace ()Ljava/lang/Object; Throwable.java
-......<< main java.lang.Throwable fillInStackTrace ()Ljava/lang/Throwable; Throwable.java
-.....<< main java.lang.Throwable <init> (Ljava/lang/String;)V Throwable.java
-....<< main java.lang.Exception <init> (Ljava/lang/String;)V Exception.java
-...<<E main Main callThrowFunction ()V Main.java
-..<< main Main doSomeWorkThrow ()V Main.java
-..>> main Main$VMDebug stopMethodTracing ()V Main.java
+..<< main Main callOuterFunction ()V Main.java
+..>> main Main callLeafFunction ()V Main.java
+..<< main Main callLeafFunction ()V Main.java
+.<< main Main $noinline$doSomeWork ()V Main.java
+.>> main Main doSomeWorkThrow ()V Main.java
+..>> main Main callThrowFunction ()V Main.java
+...>> main java.lang.Exception <init> (Ljava/lang/String;)V Exception.java
+....>> main java.lang.Throwable <init> (Ljava/lang/String;)V Throwable.java
+.....>> main java.lang.Object <init> ()V Object.java
+.....<< main java.lang.Object <init> ()V Object.java
+.....>> main java.util.Collections emptyList ()Ljava/util/List; Collections.java
+.....<< main java.util.Collections emptyList ()Ljava/util/List; Collections.java
+.....>> main java.lang.Throwable fillInStackTrace ()Ljava/lang/Throwable; Throwable.java
+......>> main java.lang.Throwable nativeFillInStackTrace ()Ljava/lang/Object; Throwable.java
+......<< main java.lang.Throwable nativeFillInStackTrace ()Ljava/lang/Object; Throwable.java
+.....<< main java.lang.Throwable fillInStackTrace ()Ljava/lang/Throwable; Throwable.java
+....<< main java.lang.Throwable <init> (Ljava/lang/String;)V Throwable.java
+...<< main java.lang.Exception <init> (Ljava/lang/String;)V Exception.java
+..<<E main Main callThrowFunction ()V Main.java
+.<< main Main doSomeWorkThrow ()V Main.java
+.>> main Main$VMDebug $noinline$stopMethodTracing ()V Main.java
diff --git a/test/2246-trace-stream/run.py b/test/2246-trace-stream/run.py
index 6881d714c8..6eb92655f8 100644
--- a/test/2246-trace-stream/run.py
+++ b/test/2246-trace-stream/run.py
@@ -18,5 +18,15 @@
def run(ctx, args):
# The expected output is different in debuggable and non debuggable. Just
# enable debuggable for now.
- # TODO(mythria): Also add tests for non-debuggable mode.
- ctx.default_run(args, Xcompiler_option=["--debuggable"])
+ ctx.default_run(args)
+
+ print(args);
+ if ("--debuggable" in args.Xcompiler_option):
+ # On debuggable runtimes we disable oat code in boot images right at the start
+ # so we get events for all methods including methods optimized in boot images.
+ ctx.expected_stdout = ctx.expected_stdout.with_suffix(".debuggable.txt")
+ elif ("--interpreter" in args.Xcompiler_option) or args.interpreter:
+ # On forced interpreter runtimes we don't get method events for optimized
+ # methods in boot images but get events for a few more methods that would
+ # have otherwise used nterp.
+ ctx.expected_stdout = ctx.expected_stdout.with_suffix(".interpreter.txt")
diff --git a/test/2246-trace-stream/src/Main.java b/test/2246-trace-stream/src/Main.java
index 39f3216d02..37870f14c1 100644
--- a/test/2246-trace-stream/src/Main.java
+++ b/test/2246-trace-stream/src/Main.java
@@ -36,19 +36,19 @@ public class Main {
Main m = new Main();
Thread t = new Thread(() -> {
Main m1 = new Main();
- m1.doSomeWork();
+ m1.$noinline$doSomeWork();
}, "TestThread2246");
try {
if (VMDebug.getMethodTracingMode() != 0) {
- VMDebug.stopMethodTracing();
+ VMDebug.$noinline$stopMethodTracing();
}
VMDebug.startMethodTracing(file.getPath(), out_file.getFD(), 0, 0, false, 0, true);
t.start();
t.join();
- m.doSomeWork();
+ m.$noinline$doSomeWork();
m.doSomeWorkThrow();
- VMDebug.stopMethodTracing();
+ VMDebug.$noinline$stopMethodTracing();
out_file.close();
m.CheckTraceFileFormat(file);
} finally {
@@ -83,7 +83,7 @@ public class Main {
if (!seen_stop_tracing_method) {
System.out.println(event_string);
}
- if (event_string.contains("Main$VMDebug stopMethodTracing")) {
+ if (event_string.contains("Main$VMDebug $noinline$stopMethodTracing")) {
seen_stop_tracing_method = true;
}
}
@@ -111,7 +111,7 @@ public class Main {
public void callLeafFunction() {}
- public void doSomeWork() {
+ public void $noinline$doSomeWork() {
callOuterFunction();
callLeafFunction();
}
@@ -150,7 +150,7 @@ public class Main {
startMethodTracingMethod.invoke(
null, filename, fd, bufferSize, flags, samplingEnabled, intervalUs, streaming);
}
- public static void stopMethodTracing() throws Exception {
+ public static void $noinline$stopMethodTracing() throws Exception {
stopMethodTracingMethod.invoke(null);
}
public static int getMethodTracingMode() throws Exception {