/*
 * Copyright (C) 2008 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 "jni_internal.h"
#include "class_loader.h"
#include "object.h"
#include "scoped_heap_lock.h"
#include "thread_list.h"

#include "JniConstants.h" // Last to avoid problems with LOG redefinition.

namespace art {

namespace {

static jobject GetThreadStack(JNIEnv* env, jobject javaThread) {
  ScopedHeapLock heap_lock;
  ScopedThreadListLock thread_list_lock;
  Thread* thread = Thread::FromManagedThread(env, javaThread);
  return (thread != NULL) ? GetThreadStack(env, thread) : NULL;
}

jint VMStack_fillStackTraceElements(JNIEnv* env, jclass, jobject javaThread, jobjectArray javaSteArray) {
  jobject trace = GetThreadStack(env, javaThread);
  if (trace == NULL) {
    return 0;
  }
  int32_t depth;
  Thread::InternalStackTraceToStackTraceElementArray(env, trace, javaSteArray, &depth);
  return depth;
}

jobject VMStack_getCallingClassLoader(JNIEnv* env, jclass) {
  // Returns the defining class loader of the caller's caller.
  // TODO: need SmartFrame (Thread::WalkStack-like iterator).
  Frame frame = Thread::Current()->GetTopOfStack();
  frame.Next();
  frame.Next();
  Method* callerCaller = frame.GetMethod();
  DCHECK(callerCaller != NULL);
  const Object* cl = callerCaller->GetDeclaringClass()->GetClassLoader();
  return AddLocalReference<jobject>(env, cl);
}

jobject VMStack_getClosestUserClassLoader(JNIEnv* env, jclass, jobject javaBootstrap, jobject javaSystem) {
  struct ClosestUserClassLoaderVisitor : public Thread::StackVisitor {
    ClosestUserClassLoaderVisitor(Object* bootstrap, Object* system)
      : bootstrap(bootstrap), system(system), class_loader(NULL) {}
    bool VisitFrame(const Frame& f, uintptr_t) {
      DCHECK(class_loader == NULL);
      Class* c = f.GetMethod()->GetDeclaringClass();
      Object* cl = c->GetClassLoader();
      if (cl != NULL && cl != bootstrap && cl != system) {
        class_loader = cl;
        return false;
      }
      return true;
    }
    Object* bootstrap;
    Object* system;
    Object* class_loader;
  };
  Object* bootstrap = Decode<Object*>(env, javaBootstrap);
  Object* system = Decode<Object*>(env, javaSystem);
  ClosestUserClassLoaderVisitor visitor(bootstrap, system);
  Thread::Current()->WalkStack(&visitor);
  return AddLocalReference<jobject>(env, visitor.class_loader);
}

jclass VMStack_getStackClass2(JNIEnv* env, jclass) {
  // Returns the class of the caller's caller's caller.
  // TODO: need SmartFrame (Thread::WalkStack-like iterator).
  Frame frame = Thread::Current()->GetTopOfStack();
  frame.Next();
  frame.Next();
  frame.Next();
  Method* callerCallerCaller = frame.GetMethod();
  DCHECK(callerCallerCaller != NULL);
  Class* c = callerCallerCaller->GetDeclaringClass();
  return AddLocalReference<jclass>(env, c);
}

jobjectArray VMStack_getThreadStackTrace(JNIEnv* env, jclass, jobject javaThread) {
  jobject trace = GetThreadStack(env, javaThread);
  if (trace == NULL) {
    return NULL;
  }
  return Thread::InternalStackTraceToStackTraceElementArray(env, trace);
}

static JNINativeMethod gMethods[] = {
  NATIVE_METHOD(VMStack, fillStackTraceElements, "(Ljava/lang/Thread;[Ljava/lang/StackTraceElement;)I"),
  NATIVE_METHOD(VMStack, getCallingClassLoader, "()Ljava/lang/ClassLoader;"),
  NATIVE_METHOD(VMStack, getClosestUserClassLoader, "(Ljava/lang/ClassLoader;Ljava/lang/ClassLoader;)Ljava/lang/ClassLoader;"),
  NATIVE_METHOD(VMStack, getStackClass2, "()Ljava/lang/Class;"),
  NATIVE_METHOD(VMStack, getThreadStackTrace, "(Ljava/lang/Thread;)[Ljava/lang/StackTraceElement;"),
};

}  // namespace

void register_dalvik_system_VMStack(JNIEnv* env) {
  jniRegisterNativeMethods(env, "dalvik/system/VMStack", gMethods, NELEM(gMethods));
}

}  // namespace art
