/*
 * Copyright (C) 2018 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 "android-base/macros.h"
#include "gc/scoped_gc_critical_section.h"
#include "instrumentation.h"
#include "runtime.h"
#include "runtime_callbacks.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-inl.h"
#include "thread_list.h"

namespace tracefast {

#if ((!defined(TRACEFAST_INTERPRETER) && !defined(TRACEFAST_TRAMPOLINE)) || \
     (defined(TRACEFAST_INTERPRETER) && defined(TRACEFAST_TRAMPOLINE)))
#error Must set one of TRACEFAST_TRAMPOLINE or TRACEFAST_INTERPRETER during build
#endif


#ifdef TRACEFAST_INTERPRETER
static constexpr const char* kTracerInstrumentationKey = "tracefast_INTERPRETER";
static constexpr bool kNeedsInterpreter = true;
#else  // defined(TRACEFAST_TRAMPOLINE)
static constexpr const char* kTracerInstrumentationKey = "tracefast_TRAMPOLINE";
static constexpr bool kNeedsInterpreter = false;
#endif  // TRACEFAST_INITERPRETER

class Tracer final : public art::instrumentation::InstrumentationListener {
 public:
  Tracer() {}

  void MethodEntered(art::Thread* thread ATTRIBUTE_UNUSED,
                     art::ArtMethod* method ATTRIBUTE_UNUSED) override
      REQUIRES_SHARED(art::Locks::mutator_lock_) {}

  void MethodExited(art::Thread* thread ATTRIBUTE_UNUSED,
                    art::ArtMethod* method ATTRIBUTE_UNUSED,
                    art::instrumentation::OptionalFrame frame ATTRIBUTE_UNUSED,
                    art::MutableHandle<art::mirror::Object>& return_value ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(art::Locks::mutator_lock_) { }

  void MethodExited(art::Thread* thread ATTRIBUTE_UNUSED,
                    art::ArtMethod* method ATTRIBUTE_UNUSED,
                    art::instrumentation::OptionalFrame frame ATTRIBUTE_UNUSED,
                    art::JValue& return_value ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(art::Locks::mutator_lock_) { }

  void MethodUnwind(art::Thread* thread ATTRIBUTE_UNUSED,
                    art::ArtMethod* method ATTRIBUTE_UNUSED,
                    uint32_t dex_pc ATTRIBUTE_UNUSED)
      override REQUIRES_SHARED(art::Locks::mutator_lock_) { }

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

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

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

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

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

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

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

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

 private:
  DISALLOW_COPY_AND_ASSIGN(Tracer);
};

Tracer gEmptyTracer;

static void StartTracing() REQUIRES(!art::Locks::mutator_lock_,
                                    !art::Locks::thread_list_lock_,
                                    !art::Locks::thread_suspend_count_lock_) {
  art::Thread* self = art::Thread::Current();
  art::Runtime* runtime = art::Runtime::Current();
  art::gc::ScopedGCCriticalSection gcs(self,
                                       art::gc::kGcCauseInstrumentation,
                                       art::gc::kCollectorTypeInstrumentation);
  art::ScopedSuspendAll ssa("starting fast tracing");
  runtime->GetInstrumentation()->AddListener(&gEmptyTracer,
                                             art::instrumentation::Instrumentation::kMethodEntered |
                                             art::instrumentation::Instrumentation::kMethodExited |
                                             art::instrumentation::Instrumentation::kMethodUnwind);
  runtime->GetInstrumentation()->EnableMethodTracing(
      kTracerInstrumentationKey, &gEmptyTracer, kNeedsInterpreter);
}

class TraceFastPhaseCB : public art::RuntimePhaseCallback {
 public:
  TraceFastPhaseCB() {}

  void NextRuntimePhase(art::RuntimePhaseCallback::RuntimePhase phase)
      override REQUIRES_SHARED(art::Locks::mutator_lock_) {
    if (phase == art::RuntimePhaseCallback::RuntimePhase::kInit) {
      art::ScopedThreadSuspension sts(art::Thread::Current(),
                                      art::ThreadState::kWaitingForMethodTracingStart);
      StartTracing();
    }
  }
};
TraceFastPhaseCB gPhaseCallback;

// The plugin initialization function.
extern "C" bool ArtPlugin_Initialize() {
  art::Runtime* runtime = art::Runtime::Current();
  art::ScopedThreadStateChange stsc(art::Thread::Current(),
                                    art::ThreadState::kWaitingForMethodTracingStart);
  art::ScopedSuspendAll ssa("Add phase callback");
  runtime->GetRuntimeCallbacks()->AddRuntimePhaseCallback(&gPhaseCallback);
  return true;
}

extern "C" bool ArtPlugin_Deinitialize() {
  // Don't need to bother doing anything.
  return true;
}

}  // namespace tracefast
