/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "instrumentation.h"

#include "android-base/macros.h"
#include "art_method-inl.h"
#include "base/enums.h"
#include "class_linker-inl.h"
#include "common_runtime_test.h"
#include "common_throws.h"
#include "dex/dex_file.h"
#include "gc/scoped_gc_critical_section.h"
#include "handle_scope-inl.h"
#include "jni/jni_internal.h"
#include "jvalue.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "interpreter/shadow_frame.h"
#include "thread-inl.h"
#include "thread_list.h"
#include "well_known_classes.h"

namespace art {
namespace instrumentation {

class TestInstrumentationListener final : public instrumentation::InstrumentationListener {
 public:
  TestInstrumentationListener()
    : received_method_enter_event(false),
      received_method_exit_event(false),
      received_method_exit_object_event(false),
      received_method_unwind_event(false),
      received_dex_pc_moved_event(false),
      received_field_read_event(false),
      received_field_written_event(false),
      received_field_written_object_event(false),
      received_exception_thrown_event(false),
      received_exception_handled_event(false),
      received_branch_event(false),
      received_watched_frame_pop(false) {}

  virtual ~TestInstrumentationListener() {}

  void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
                     Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
                     ArtMethod* method ATTRIBUTE_UNUSED,
                     uint32_t dex_pc ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_method_enter_event = true;
  }

  void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
                    Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
                    ArtMethod* method ATTRIBUTE_UNUSED,
                    uint32_t dex_pc ATTRIBUTE_UNUSED,
                    instrumentation::OptionalFrame frame ATTRIBUTE_UNUSED,
                    MutableHandle<mirror::Object>& return_value ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_method_exit_object_event = true;
  }

  void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
                    Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
                    ArtMethod* method ATTRIBUTE_UNUSED,
                    uint32_t dex_pc ATTRIBUTE_UNUSED,
                    instrumentation::OptionalFrame frame ATTRIBUTE_UNUSED,
                    JValue& return_value ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_method_exit_event = true;
  }

  void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
                    Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
                    ArtMethod* method ATTRIBUTE_UNUSED,
                    uint32_t dex_pc ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_method_unwind_event = true;
  }

  void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
                  Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
                  ArtMethod* method ATTRIBUTE_UNUSED,
                  uint32_t new_dex_pc ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_dex_pc_moved_event = true;
  }

  void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
                 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
                 ArtMethod* method ATTRIBUTE_UNUSED,
                 uint32_t dex_pc ATTRIBUTE_UNUSED,
                 ArtField* field ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_field_read_event = true;
  }

  void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
                    Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
                    ArtMethod* method ATTRIBUTE_UNUSED,
                    uint32_t dex_pc ATTRIBUTE_UNUSED,
                    ArtField* field ATTRIBUTE_UNUSED,
                    Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_field_written_object_event = true;
  }

  void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
                    Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
                    ArtMethod* method ATTRIBUTE_UNUSED,
                    uint32_t dex_pc ATTRIBUTE_UNUSED,
                    ArtField* field ATTRIBUTE_UNUSED,
                    const JValue& field_value ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_field_written_event = true;
  }

  void ExceptionThrown(Thread* thread ATTRIBUTE_UNUSED,
                       Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_exception_thrown_event = true;
  }

  void ExceptionHandled(Thread* self ATTRIBUTE_UNUSED,
                        Handle<mirror::Throwable> throwable ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_exception_handled_event = true;
  }

  void Branch(Thread* thread ATTRIBUTE_UNUSED,
              ArtMethod* method ATTRIBUTE_UNUSED,
              uint32_t dex_pc ATTRIBUTE_UNUSED,
              int32_t dex_pc_offset ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_branch_event = true;
  }

  void WatchedFramePop(Thread* thread ATTRIBUTE_UNUSED, const ShadowFrame& frame ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(Locks::mutator_lock_) {
    received_watched_frame_pop  = true;
  }

  void Reset() {
    received_method_enter_event = false;
    received_method_exit_event = false;
    received_method_exit_object_event = false;
    received_method_unwind_event = false;
    received_dex_pc_moved_event = false;
    received_field_read_event = false;
    received_field_written_event = false;
    received_field_written_object_event = false;
    received_exception_thrown_event = false;
    received_exception_handled_event = false;
    received_branch_event = false;
    received_watched_frame_pop = false;
  }

  bool received_method_enter_event;
  bool received_method_exit_event;
  bool received_method_exit_object_event;
  bool received_method_unwind_event;
  bool received_dex_pc_moved_event;
  bool received_field_read_event;
  bool received_field_written_event;
  bool received_field_written_object_event;
  bool received_exception_thrown_event;
  bool received_exception_handled_event;
  bool received_branch_event;
  bool received_watched_frame_pop;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
};

class InstrumentationTest : public CommonRuntimeTest {
 public:
  // Unique keys used to test Instrumentation::ConfigureStubs.
  static constexpr const char* kClientOneKey = "TestClient1";
  static constexpr const char* kClientTwoKey = "TestClient2";

  void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
    ScopedObjectAccess soa(Thread::Current());
    instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
    ScopedThreadSuspension sts(soa.Self(), kSuspended);
    gc::ScopedGCCriticalSection gcs(soa.Self(),
                                    gc::kGcCauseInstrumentation,
                                    gc::kCollectorTypeInstrumentation);
    ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
    instr->ConfigureStubs(key, level);
  }

  Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
    return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
  }

  size_t GetInstrumentationUserCount() {
    ScopedObjectAccess soa(Thread::Current());
    return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
  }

  void TestEvent(uint32_t instrumentation_event) {
    TestEvent(instrumentation_event, nullptr, nullptr, false);
  }

  void TestEvent(uint32_t instrumentation_event,
                 ArtMethod* event_method,
                 ArtField* event_field,
                 bool with_object) {
    ScopedObjectAccess soa(Thread::Current());
    instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
    TestInstrumentationListener listener;
    {
      ScopedThreadSuspension sts(soa.Self(), kSuspended);
      ScopedSuspendAll ssa("Add instrumentation listener");
      instr->AddListener(&listener, instrumentation_event);
    }

    mirror::Object* const event_obj = nullptr;
    const uint32_t event_dex_pc = 0;
    ShadowFrameAllocaUniquePtr test_frame = CREATE_SHADOW_FRAME(0, nullptr, event_method, 0);

    // Check the listener is registered and is notified of the event.
    EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
    EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
    ReportEvent(instr,
                instrumentation_event,
                soa.Self(),
                event_method,
                event_obj,
                event_field,
                event_dex_pc,
                *test_frame);
    EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));

    listener.Reset();
    {
      ScopedThreadSuspension sts(soa.Self(), kSuspended);
      ScopedSuspendAll ssa("Remove instrumentation listener");
      instr->RemoveListener(&listener, instrumentation_event);
    }

    // Check the listener is not registered and is not notified of the event.
    EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
    EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
    ReportEvent(instr,
                instrumentation_event,
                soa.Self(),
                event_method,
                event_obj,
                event_field,
                event_dex_pc,
                *test_frame);
    EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
  }

  void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    Runtime* runtime = Runtime::Current();
    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
    ScopedThreadSuspension sts(self, kSuspended);
    gc::ScopedGCCriticalSection gcs(self,
                                    gc::kGcCauseInstrumentation,
                                    gc::kCollectorTypeInstrumentation);
    ScopedSuspendAll ssa("Single method deoptimization");
    if (enable_deoptimization) {
      instrumentation->EnableDeoptimization();
    }
    instrumentation->Deoptimize(method);
  }

  void UndeoptimizeMethod(Thread* self, ArtMethod* method,
                          const char* key, bool disable_deoptimization)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    Runtime* runtime = Runtime::Current();
    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
    ScopedThreadSuspension sts(self, kSuspended);
    gc::ScopedGCCriticalSection gcs(self,
                                    gc::kGcCauseInstrumentation,
                                    gc::kCollectorTypeInstrumentation);
    ScopedSuspendAll ssa("Single method undeoptimization");
    instrumentation->Undeoptimize(method);
    if (disable_deoptimization) {
      instrumentation->DisableDeoptimization(key);
    }
  }

  void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
        REQUIRES_SHARED(Locks::mutator_lock_) {
    Runtime* runtime = Runtime::Current();
    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
    ScopedThreadSuspension sts(self, kSuspended);
    gc::ScopedGCCriticalSection gcs(self,
                                    gc::kGcCauseInstrumentation,
                                    gc::kCollectorTypeInstrumentation);
    ScopedSuspendAll ssa("Full deoptimization");
    if (enable_deoptimization) {
      instrumentation->EnableDeoptimization();
    }
    instrumentation->DeoptimizeEverything(key);
  }

  void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
        REQUIRES_SHARED(Locks::mutator_lock_) {
    Runtime* runtime = Runtime::Current();
    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
    ScopedThreadSuspension sts(self, kSuspended);
    gc::ScopedGCCriticalSection gcs(self,
                                    gc::kGcCauseInstrumentation,
                                    gc::kCollectorTypeInstrumentation);
    ScopedSuspendAll ssa("Full undeoptimization");
    instrumentation->UndeoptimizeEverything(key);
    if (disable_deoptimization) {
      instrumentation->DisableDeoptimization(key);
    }
  }

  void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
        REQUIRES_SHARED(Locks::mutator_lock_) {
    Runtime* runtime = Runtime::Current();
    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
    ScopedThreadSuspension sts(self, kSuspended);
    gc::ScopedGCCriticalSection gcs(self,
                                    gc::kGcCauseInstrumentation,
                                    gc::kCollectorTypeInstrumentation);
    ScopedSuspendAll ssa("EnableMethodTracing");
    instrumentation->EnableMethodTracing(key, needs_interpreter);
  }

  void DisableMethodTracing(Thread* self, const char* key)
        REQUIRES_SHARED(Locks::mutator_lock_) {
    Runtime* runtime = Runtime::Current();
    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
    ScopedThreadSuspension sts(self, kSuspended);
    gc::ScopedGCCriticalSection gcs(self,
                                    gc::kGcCauseInstrumentation,
                                    gc::kCollectorTypeInstrumentation);
    ScopedSuspendAll ssa("EnableMethodTracing");
    instrumentation->DisableMethodTracing(key);
  }

 private:
  static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    switch (event_type) {
      case instrumentation::Instrumentation::kMethodEntered:
        return instr->HasMethodEntryListeners();
      case instrumentation::Instrumentation::kMethodExited:
        return instr->HasMethodExitListeners();
      case instrumentation::Instrumentation::kMethodUnwind:
        return instr->HasMethodUnwindListeners();
      case instrumentation::Instrumentation::kDexPcMoved:
        return instr->HasDexPcListeners();
      case instrumentation::Instrumentation::kFieldRead:
        return instr->HasFieldReadListeners();
      case instrumentation::Instrumentation::kFieldWritten:
        return instr->HasFieldWriteListeners();
      case instrumentation::Instrumentation::kExceptionThrown:
        return instr->HasExceptionThrownListeners();
      case instrumentation::Instrumentation::kExceptionHandled:
        return instr->HasExceptionHandledListeners();
      case instrumentation::Instrumentation::kBranch:
        return instr->HasBranchListeners();
      case instrumentation::Instrumentation::kWatchedFramePop:
        return instr->HasWatchedFramePopListeners();
      default:
        LOG(FATAL) << "Unknown instrumentation event " << event_type;
        UNREACHABLE();
    }
  }

  static void ReportEvent(const instrumentation::Instrumentation* instr,
                          uint32_t event_type,
                          Thread* self,
                          ArtMethod* method,
                          mirror::Object* obj,
                          ArtField* field,
                          uint32_t dex_pc,
                          const ShadowFrame& frame)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    switch (event_type) {
      case instrumentation::Instrumentation::kMethodEntered:
        instr->MethodEnterEvent(self, obj, method, dex_pc);
        break;
      case instrumentation::Instrumentation::kMethodExited: {
        JValue value;
        instr->MethodExitEvent(self, obj, method, dex_pc, {}, value);
        break;
      }
      case instrumentation::Instrumentation::kMethodUnwind:
        instr->MethodUnwindEvent(self, obj, method, dex_pc);
        break;
      case instrumentation::Instrumentation::kDexPcMoved:
        instr->DexPcMovedEvent(self, obj, method, dex_pc);
        break;
      case instrumentation::Instrumentation::kFieldRead:
        instr->FieldReadEvent(self, obj, method, dex_pc, field);
        break;
      case instrumentation::Instrumentation::kFieldWritten: {
        JValue value;
        instr->FieldWriteEvent(self, obj, method, dex_pc, field, value);
        break;
      }
      case instrumentation::Instrumentation::kExceptionThrown: {
        ThrowArithmeticExceptionDivideByZero();
        mirror::Throwable* event_exception = self->GetException();
        instr->ExceptionThrownEvent(self, event_exception);
        self->ClearException();
        break;
      }
      case instrumentation::Instrumentation::kBranch:
        instr->Branch(self, method, dex_pc, -1);
        break;
      case instrumentation::Instrumentation::kWatchedFramePop:
        instr->WatchedFramePopped(self, frame);
        break;
      case instrumentation::Instrumentation::kExceptionHandled: {
        ThrowArithmeticExceptionDivideByZero();
        mirror::Throwable* event_exception = self->GetException();
        self->ClearException();
        instr->ExceptionHandledEvent(self, event_exception);
        break;
      }
      default:
        LOG(FATAL) << "Unknown instrumentation event " << event_type;
        UNREACHABLE();
    }
  }

  static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
                                      uint32_t event_type,
                                      bool with_object) {
    switch (event_type) {
      case instrumentation::Instrumentation::kMethodEntered:
        return listener.received_method_enter_event;
      case instrumentation::Instrumentation::kMethodExited:
        return (!with_object && listener.received_method_exit_event) ||
            (with_object && listener.received_method_exit_object_event);
      case instrumentation::Instrumentation::kMethodUnwind:
        return listener.received_method_unwind_event;
      case instrumentation::Instrumentation::kDexPcMoved:
        return listener.received_dex_pc_moved_event;
      case instrumentation::Instrumentation::kFieldRead:
        return listener.received_field_read_event;
      case instrumentation::Instrumentation::kFieldWritten:
        return (!with_object && listener.received_field_written_event) ||
            (with_object && listener.received_field_written_object_event);
      case instrumentation::Instrumentation::kExceptionThrown:
        return listener.received_exception_thrown_event;
      case instrumentation::Instrumentation::kExceptionHandled:
        return listener.received_exception_handled_event;
      case instrumentation::Instrumentation::kBranch:
        return listener.received_branch_event;
      case instrumentation::Instrumentation::kWatchedFramePop:
        return listener.received_watched_frame_pop;
      default:
        LOG(FATAL) << "Unknown instrumentation event " << event_type;
        UNREACHABLE();
    }
  }
};

TEST_F(InstrumentationTest, NoInstrumentation) {
  ScopedObjectAccess soa(Thread::Current());
  instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
  ASSERT_NE(instr, nullptr);

  EXPECT_FALSE(instr->AreExitStubsInstalled());
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_FALSE(instr->IsActive());
  EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());

  // Test interpreter table is the default one.
  EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());

  // Check there is no registered listener.
  EXPECT_FALSE(instr->HasDexPcListeners());
  EXPECT_FALSE(instr->HasExceptionThrownListeners());
  EXPECT_FALSE(instr->HasExceptionHandledListeners());
  EXPECT_FALSE(instr->HasFieldReadListeners());
  EXPECT_FALSE(instr->HasFieldWriteListeners());
  EXPECT_FALSE(instr->HasMethodEntryListeners());
  EXPECT_FALSE(instr->HasMethodExitListeners());
  EXPECT_FALSE(instr->IsActive());
}

// Test instrumentation listeners for each event.
TEST_F(InstrumentationTest, MethodEntryEvent) {
  ScopedObjectAccess soa(Thread::Current());
  jobject class_loader = LoadDex("Instrumentation");
  Runtime* const runtime = Runtime::Current();
  ClassLinker* class_linker = runtime->GetClassLinker();
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
  ASSERT_TRUE(klass != nullptr);
  ArtMethod* method =
      klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
  ASSERT_TRUE(method != nullptr);
  ASSERT_TRUE(method->IsDirect());
  ASSERT_TRUE(method->GetDeclaringClass() == klass);
  TestEvent(instrumentation::Instrumentation::kMethodEntered,
            /*event_method=*/ method,
            /*event_field=*/ nullptr,
            /*with_object=*/ true);
}

TEST_F(InstrumentationTest, MethodExitObjectEvent) {
  ScopedObjectAccess soa(Thread::Current());
  jobject class_loader = LoadDex("Instrumentation");
  Runtime* const runtime = Runtime::Current();
  ClassLinker* class_linker = runtime->GetClassLinker();
  StackHandleScope<1> hs(soa.Self());
  MutableHandle<mirror::ClassLoader> loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
  ASSERT_TRUE(klass != nullptr);
  ArtMethod* method =
      klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
  ASSERT_TRUE(method != nullptr);
  ASSERT_TRUE(method->IsDirect());
  ASSERT_TRUE(method->GetDeclaringClass() == klass);
  TestEvent(instrumentation::Instrumentation::kMethodExited,
            /*event_method=*/ method,
            /*event_field=*/ nullptr,
            /*with_object=*/ true);
}

TEST_F(InstrumentationTest, MethodExitPrimEvent) {
  ScopedObjectAccess soa(Thread::Current());
  jobject class_loader = LoadDex("Instrumentation");
  Runtime* const runtime = Runtime::Current();
  ClassLinker* class_linker = runtime->GetClassLinker();
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
  ASSERT_TRUE(klass != nullptr);
  ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
  ASSERT_TRUE(method != nullptr);
  ASSERT_TRUE(method->IsDirect());
  ASSERT_TRUE(method->GetDeclaringClass() == klass);
  TestEvent(instrumentation::Instrumentation::kMethodExited,
            /*event_method=*/ method,
            /*event_field=*/ nullptr,
            /*with_object=*/ false);
}

TEST_F(InstrumentationTest, MethodUnwindEvent) {
  TestEvent(instrumentation::Instrumentation::kMethodUnwind);
}

TEST_F(InstrumentationTest, DexPcMovedEvent) {
  TestEvent(instrumentation::Instrumentation::kDexPcMoved);
}

TEST_F(InstrumentationTest, FieldReadEvent) {
  TestEvent(instrumentation::Instrumentation::kFieldRead);
}

TEST_F(InstrumentationTest, WatchedFramePop) {
  TestEvent(instrumentation::Instrumentation::kWatchedFramePop);
}

TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
  ScopedObjectAccess soa(Thread::Current());
  jobject class_loader = LoadDex("Instrumentation");
  Runtime* const runtime = Runtime::Current();
  ClassLinker* class_linker = runtime->GetClassLinker();
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
  ASSERT_TRUE(klass != nullptr);
  ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
  ASSERT_TRUE(field != nullptr);

  TestEvent(instrumentation::Instrumentation::kFieldWritten,
            /*event_method=*/ nullptr,
            /*event_field=*/ field,
            /*with_object=*/ true);
}

TEST_F(InstrumentationTest, FieldWritePrimEvent) {
  ScopedObjectAccess soa(Thread::Current());
  jobject class_loader = LoadDex("Instrumentation");
  Runtime* const runtime = Runtime::Current();
  ClassLinker* class_linker = runtime->GetClassLinker();
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
  ASSERT_TRUE(klass != nullptr);
  ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
  ASSERT_TRUE(field != nullptr);

  TestEvent(instrumentation::Instrumentation::kFieldWritten,
            /*event_method=*/ nullptr,
            /*event_field=*/ field,
            /*with_object=*/ false);
}

TEST_F(InstrumentationTest, ExceptionHandledEvent) {
  TestEvent(instrumentation::Instrumentation::kExceptionHandled);
}

TEST_F(InstrumentationTest, ExceptionThrownEvent) {
  TestEvent(instrumentation::Instrumentation::kExceptionThrown);
}

TEST_F(InstrumentationTest, BranchEvent) {
  TestEvent(instrumentation::Instrumentation::kBranch);
}

TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
  ScopedObjectAccess soa(Thread::Current());
  jobject class_loader = LoadDex("Instrumentation");
  Runtime* const runtime = Runtime::Current();
  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
  ClassLinker* class_linker = runtime->GetClassLinker();
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
  ASSERT_TRUE(klass != nullptr);
  ArtMethod* method_to_deoptimize =
      klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
  ASSERT_TRUE(method_to_deoptimize != nullptr);
  ASSERT_TRUE(method_to_deoptimize->IsDirect());
  ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);

  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));

  DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);

  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_TRUE(instr->AreExitStubsInstalled());
  EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));

  constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
  UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);

  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
}

TEST_F(InstrumentationTest, FullDeoptimization) {
  ScopedObjectAccess soa(Thread::Current());
  Runtime* const runtime = Runtime::Current();
  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());

  constexpr const char* instrumentation_key = "FullDeoptimization";
  DeoptimizeEverything(soa.Self(), instrumentation_key, true);

  EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
  EXPECT_TRUE(instr->AreExitStubsInstalled());

  UndeoptimizeEverything(soa.Self(), instrumentation_key, true);

  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
}

TEST_F(InstrumentationTest, MixedDeoptimization) {
  ScopedObjectAccess soa(Thread::Current());
  jobject class_loader = LoadDex("Instrumentation");
  Runtime* const runtime = Runtime::Current();
  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
  ClassLinker* class_linker = runtime->GetClassLinker();
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
  ASSERT_TRUE(klass != nullptr);
  ArtMethod* method_to_deoptimize =
      klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
  ASSERT_TRUE(method_to_deoptimize != nullptr);
  ASSERT_TRUE(method_to_deoptimize->IsDirect());
  ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);

  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));

  DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
  // Deoptimizing a method does not change instrumentation level.
  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
            GetCurrentInstrumentationLevel());
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_TRUE(instr->AreExitStubsInstalled());
  EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));

  constexpr const char* instrumentation_key = "MixedDeoptimization";
  DeoptimizeEverything(soa.Self(), instrumentation_key, false);
  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
            GetCurrentInstrumentationLevel());
  EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
  EXPECT_TRUE(instr->AreExitStubsInstalled());
  EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));

  UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
            GetCurrentInstrumentationLevel());
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_TRUE(instr->AreExitStubsInstalled());
  EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));

  UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
            GetCurrentInstrumentationLevel());
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
}

TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
  ScopedObjectAccess soa(Thread::Current());
  Runtime* const runtime = Runtime::Current();
  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());

  constexpr const char* instrumentation_key = "MethodTracing";
  EnableMethodTracing(soa.Self(), instrumentation_key, true);
  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
            GetCurrentInstrumentationLevel());
  EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
  EXPECT_TRUE(instr->AreExitStubsInstalled());

  DisableMethodTracing(soa.Self(), instrumentation_key);
  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
            GetCurrentInstrumentationLevel());
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
}

TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
  ScopedObjectAccess soa(Thread::Current());
  Runtime* const runtime = Runtime::Current();
  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());

  constexpr const char* instrumentation_key = "MethodTracing";
  EnableMethodTracing(soa.Self(), instrumentation_key, false);
  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
            GetCurrentInstrumentationLevel());
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
  EXPECT_TRUE(instr->AreExitStubsInstalled());

  DisableMethodTracing(soa.Self(), instrumentation_key);
  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
            GetCurrentInstrumentationLevel());
  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
}

// We use a macro to print the line number where the test is failing.
#define CHECK_INSTRUMENTATION(_level, _user_count)                                      \
  do {                                                                                  \
    Instrumentation* const instr = Runtime::Current()->GetInstrumentation();            \
    bool interpreter =                                                                  \
      ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);  \
    EXPECT_EQ(_level, GetCurrentInstrumentationLevel());                                \
    EXPECT_EQ(_user_count, GetInstrumentationUserCount());                              \
    if (instr->IsForcedInterpretOnly()) {                                               \
      EXPECT_TRUE(instr->InterpretOnly());                                              \
    } else if (interpreter) {                                                           \
      EXPECT_TRUE(instr->InterpretOnly());                                              \
    } else {                                                                            \
      EXPECT_FALSE(instr->InterpretOnly());                                             \
    }                                                                                   \
    if (interpreter) {                                                                  \
      EXPECT_TRUE(instr->AreAllMethodsDeoptimized());                                   \
    } else {                                                                            \
      EXPECT_FALSE(instr->AreAllMethodsDeoptimized());                                  \
    }                                                                                   \
  } while (false)

TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Check no-op.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Check we can switch to instrumentation stubs
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
                        1U);

  // Check we can disable instrumentation.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Check we can switch to interpreter
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);

  // Check we can disable instrumentation.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Configure stubs with instrumentation stubs.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
                        1U);

  // Configure stubs with interpreter.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);

  // Check we can disable instrumentation.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Configure stubs with interpreter.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);

  // Configure stubs with instrumentation stubs.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  // Make sure we are still interpreter since going from interpreter->instrumentation is dangerous.
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
                        1U);

  // Check we can disable instrumentation.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest,
       ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Configure stubs with instrumentation stubs.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
                        1U);

  // Configure stubs with interpreter.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);

  // Configure stubs with instrumentation stubs again.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
                        1U);

  // Check we can disable instrumentation.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Check kInstrumentNothing with two clients.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Configure stubs with instrumentation stubs for 1st client.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
                        1U);

  // Configure stubs with instrumentation stubs for 2nd client.
  CheckConfigureStubs(kClientTwoKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
                        2U);

  // 1st client requests instrumentation deactivation but 2nd client still needs
  // instrumentation stubs.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
                        1U);

  // 2nd client requests instrumentation deactivation
  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Configure stubs with interpreter for 1st client.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);

  // Configure stubs with interpreter for 2nd client.
  CheckConfigureStubs(kClientTwoKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);

  // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);

  // 2nd client requests instrumentation deactivation
  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Configure stubs with instrumentation stubs for 1st client.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
                        1U);

  // Configure stubs with interpreter for 2nd client.
  CheckConfigureStubs(kClientTwoKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);

  // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);

  // 2nd client requests instrumentation deactivation
  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);

  // Configure stubs with interpreter for 1st client.
  CheckConfigureStubs(kClientOneKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);

  // Configure stubs with instrumentation stubs for 2nd client.
  CheckConfigureStubs(kClientTwoKey,
                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);

  // 1st client requests instrumentation deactivation but 2nd client still needs
  // instrumentation stubs. Since we already got interpreter stubs we need to stay there.
  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
                        1U);

  // 2nd client requests instrumentation deactivation
  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
}

}  // namespace instrumentation
}  // namespace art
