/*
 * 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 <unistd.h>
#include <limits.h>

#include "heap.h"
#include "jni_internal.h"
#include "object.h"
#include "runtime.h"

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

namespace art {

namespace {

void Runtime_gc(JNIEnv*, jclass) {
  Heap::CollectGarbage();
}

void Runtime_nativeExit(JNIEnv* env, jclass, jint status, jboolean isExit) {
  // isExit is true for System.exit and false for System.halt.
  if (isExit) {
    Runtime::Current()->CallExitHook(status);
  }
  exit(status);
}

/*
 * static String nativeLoad(String filename, ClassLoader loader)
 *
 * Load the specified full path as a dynamic library filled with
 * JNI-compatible methods. Returns null on success, or a failure
 * message on failure.
 */
jstring Runtime_nativeLoad(JNIEnv* env, jclass, jstring javaFilename, jobject javaLoader) {
  ScopedUtfChars filename(env, javaFilename);
  if (filename.c_str() == NULL) {
    return NULL;
  }

  ClassLoader* classLoader = Decode<ClassLoader*>(env, javaLoader);
  std::string detail;
  JavaVMExt* vm = Runtime::Current()->GetJavaVM();
  bool success = vm->LoadNativeLibrary(filename.c_str(), classLoader, detail);
  if (success) {
    return NULL;
  }

  return env->NewStringUTF(detail.c_str());
}

jlong Runtime_maxMemory(JNIEnv* env, jclass) {
  return Heap::GetMaxMemory();
}

jlong Runtime_totalMemory(JNIEnv* env, jclass) {
  return Heap::GetTotalMemory();
}

jlong Runtime_freeMemory(JNIEnv* env, jclass) {
  return Heap::GetFreeMemory();
}

static JNINativeMethod gMethods[] = {
    NATIVE_METHOD(Runtime, freeMemory, "()J"),
    NATIVE_METHOD(Runtime, gc, "()V"),
    NATIVE_METHOD(Runtime, maxMemory, "()J"),
    NATIVE_METHOD(Runtime, nativeExit, "(IZ)V"),
    NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;"),
    NATIVE_METHOD(Runtime, totalMemory, "()J"),
};

}  // namespace

void register_java_lang_Runtime(JNIEnv* env) {
    jniRegisterNativeMethods(env, "java/lang/Runtime", gMethods, NELEM(gMethods));
}

}  // namespace art
