/*
 * Copyright (C) 2011 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 <dlfcn.h>

#include <cstdarg>
#include <utility>
#include <vector>

#include "class_linker.h"
#include "class_loader.h"
#include "jni.h"
#include "logging.h"
#include "mutex.h"
#include "object.h"
#include "object_utils.h"
#include "runtime.h"
#include "safe_map.h"
#include "scoped_thread_state_change.h"
#include "ScopedLocalRef.h"
#include "stl_util.h"
#include "stringpiece.h"
#include "thread.h"
#include "UniquePtr.h"
#include "well_known_classes.h"

namespace art {

static const size_t kMonitorsInitial = 32; // Arbitrary.
static const size_t kMonitorsMax = 4096; // Arbitrary sanity check.

static const size_t kLocalsInitial = 64; // Arbitrary.
static const size_t kLocalsMax = 512; // Arbitrary sanity check.

static const size_t kPinTableInitial = 16; // Arbitrary.
static const size_t kPinTableMax = 1024; // Arbitrary sanity check.

static size_t gGlobalsInitial = 512; // Arbitrary.
static size_t gGlobalsMax = 51200; // Arbitrary sanity check.

static const size_t kWeakGlobalsInitial = 16; // Arbitrary.
static const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check.

void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
                           size_t method_count) {
  ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
  if (c.get() == NULL) {
    LOG(FATAL) << "Couldn't find class: " << jni_class_name;
  }
  if (env->RegisterNatives(c.get(), methods, method_count) != JNI_OK) {
    LOG(FATAL) << "Failed to register natives methods: " << jni_class_name;
  }
}

void SetJniGlobalsMax(size_t max) {
  if (max != 0) {
    gGlobalsMax = max;
    gGlobalsInitial = std::min(gGlobalsInitial, gGlobalsMax);
  }
}

size_t NumArgArrayBytes(const char* shorty, uint32_t shorty_len) {
  size_t num_bytes = 0;
  for (size_t i = 1; i < shorty_len; ++i) {
    char ch = shorty[i];
    if (ch == 'D' || ch == 'J') {
      num_bytes += 8;
    } else if (ch == 'L') {
      // Argument is a reference or an array.  The shorty descriptor
      // does not distinguish between these types.
      num_bytes += sizeof(Object*);
    } else {
      num_bytes += 4;
    }
  }
  return num_bytes;
}

class ArgArray {
 public:
  explicit ArgArray(AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    MethodHelper mh(method);
    shorty_ = mh.GetShorty();
    shorty_len_ = mh.GetShortyLength();
    if (shorty_len_ - 1 < kSmallArgArraySize) {
      arg_array_ = small_arg_array_;
    } else {
      large_arg_array_.reset(new JValue[shorty_len_ - 1]);
      arg_array_ = large_arg_array_.get();
    }
  }

  JValue* get() {
    return arg_array_;
  }

  void BuildArgArray(const ScopedObjectAccess& soa, va_list ap)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    for (size_t i = 1, offset = 0; i < shorty_len_; ++i, ++offset) {
      switch (shorty_[i]) {
        case 'Z':
          arg_array_[offset].SetZ(va_arg(ap, jint));
          break;
        case 'B':
          arg_array_[offset].SetB(va_arg(ap, jint));
          break;
        case 'C':
          arg_array_[offset].SetC(va_arg(ap, jint));
          break;
        case 'S':
          arg_array_[offset].SetS(va_arg(ap, jint));
          break;
        case 'I':
          arg_array_[offset].SetI(va_arg(ap, jint));
          break;
        case 'F':
          arg_array_[offset].SetF(va_arg(ap, jdouble));
          break;
        case 'L':
          arg_array_[offset].SetL(soa.Decode<Object*>(va_arg(ap, jobject)));
          break;
        case 'D':
          arg_array_[offset].SetD(va_arg(ap, jdouble));
          break;
        case 'J':
          arg_array_[offset].SetJ(va_arg(ap, jlong));
          break;
      }
    }
  }

  void BuildArgArray(const ScopedObjectAccess& soa, jvalue* args)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    for (size_t i = 1, offset = 0; i < shorty_len_; ++i, ++offset) {
      switch (shorty_[i]) {
        case 'Z':
          arg_array_[offset].SetZ(args[offset].z);
          break;
        case 'B':
          arg_array_[offset].SetB(args[offset].b);
          break;
        case 'C':
          arg_array_[offset].SetC(args[offset].c);
          break;
        case 'S':
          arg_array_[offset].SetS(args[offset].s);
          break;
        case 'I':
          arg_array_[offset].SetI(args[offset].i);
          break;
        case 'F':
          arg_array_[offset].SetF(args[offset].f);
          break;
        case 'L':
          arg_array_[offset].SetL(soa.Decode<Object*>(args[offset].l));
          break;
        case 'D':
          arg_array_[offset].SetD(args[offset].d);
          break;
        case 'J':
          arg_array_[offset].SetJ(args[offset].j);
          break;
      }
    }
  }

 private:
  enum { kSmallArgArraySize = 16 };
  const char* shorty_;
  uint32_t shorty_len_;
  JValue* arg_array_;
  JValue small_arg_array_[kSmallArgArraySize];
  UniquePtr<JValue[]> large_arg_array_;
};

static jweak AddWeakGlobalReference(ScopedObjectAccess& soa, Object* obj)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  if (obj == NULL) {
    return NULL;
  }
  JavaVMExt* vm = soa.Vm();
  IndirectReferenceTable& weak_globals = vm->weak_globals;
  MutexLock mu(vm->weak_globals_lock);
  IndirectRef ref = weak_globals.Add(IRT_FIRST_SEGMENT, obj);
  return reinterpret_cast<jweak>(ref);
}

static void CheckMethodArguments(AbstractMethod* m, JValue* args)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  MethodHelper mh(m);
  ObjectArray<Class>* parameter_types = mh.GetParameterTypes();
  CHECK(parameter_types != NULL);
  size_t error_count = 0;
  for (int i = 0; i < parameter_types->GetLength(); ++i) {
    Class* parameter_type = parameter_types->Get(i);
    // TODO: check primitives are in range.
    if (!parameter_type->IsPrimitive()) {
      Object* argument = args[i].GetL();
      if (argument != NULL && !argument->InstanceOf(parameter_type)) {
        LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of "
                   << PrettyTypeOf(argument) << " as argument " << (i + 1) << " to " << PrettyMethod(m);
        ++error_count;
      }
    }
  }
  if (error_count > 0) {
    // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort
    // with an argument.
    JniAbortF(NULL, "bad arguments passed to %s (see above for details)", PrettyMethod(m).c_str());
  }
}

static JValue InvokeWithArgArray(const ScopedObjectAccess& soa, Object* receiver,
                                 AbstractMethod* method, JValue* args)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  if (UNLIKELY(soa.Env()->check_jni)) {
    CheckMethodArguments(method, args);
  }
  JValue result;
  method->Invoke(soa.Self(), receiver, args, &result);
  return result;
}

static JValue InvokeWithVarArgs(const ScopedObjectAccess& soa, jobject obj,
                                jmethodID mid, va_list args)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  Object* receiver = soa.Decode<Object*>(obj);
  AbstractMethod* method = soa.DecodeMethod(mid);
  ArgArray arg_array(method);
  arg_array.BuildArgArray(soa, args);
  return InvokeWithArgArray(soa, receiver, method, arg_array.get());
}

static AbstractMethod* FindVirtualMethod(Object* receiver, AbstractMethod* method)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method);
}

static JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccess& soa,
                                                  jobject obj, jmethodID mid, jvalue* args)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  Object* receiver = soa.Decode<Object*>(obj);
  AbstractMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
  ArgArray arg_array(method);
  arg_array.BuildArgArray(soa, args);
  return InvokeWithArgArray(soa, receiver, method, arg_array.get());
}

static JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccess& soa,
                                                  jobject obj, jmethodID mid, va_list args)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  Object* receiver = soa.Decode<Object*>(obj);
  AbstractMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
  ArgArray arg_array(method);
  arg_array.BuildArgArray(soa, args);
  return InvokeWithArgArray(soa, receiver, method, arg_array.get());
}

// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
// separated with slashes but aren't wrapped with "L;" like regular descriptors
// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
// supported names with dots too (such as "a.b.C").
static std::string NormalizeJniClassDescriptor(const char* name) {
  std::string result;
  // Add the missing "L;" if necessary.
  if (name[0] == '[') {
    result = name;
  } else {
    result += 'L';
    result += name;
    result += ';';
  }
  // Rewrite '.' as '/' for backwards compatibility.
  if (result.find('.') != std::string::npos) {
    LOG(WARNING) << "Call to JNI FindClass with dots in name: "
                 << "\"" << name << "\"";
    std::replace(result.begin(), result.end(), '.', '/');
  }
  return result;
}

static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, Class* c,
                                   const char* name, const char* sig, const char* kind)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
      "no %s method \"%s.%s%s\"", kind, ClassHelper(c).GetDescriptor(), name, sig);
}

static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
                              const char* name, const char* sig, bool is_static)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  Class* c = soa.Decode<Class*>(jni_class);
  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
    return NULL;
  }

  AbstractMethod* method = NULL;
  if (is_static) {
    method = c->FindDirectMethod(name, sig);
  } else {
    method = c->FindVirtualMethod(name, sig);
    if (method == NULL) {
      // No virtual method matching the signature.  Search declared
      // private methods and constructors.
      method = c->FindDeclaredDirectMethod(name, sig);
    }
  }

  if (method == NULL || method->IsStatic() != is_static) {
    ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
    return NULL;
  }

  return soa.EncodeMethod(method);
}

static ClassLoader* GetClassLoader(Thread* self)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  AbstractMethod* method = self->GetCurrentMethod();
  if (method == NULL || PrettyMethod(method, false) == "java.lang.Runtime.nativeLoad") {
    return self->GetClassLoaderOverride();
  }
  return method->GetDeclaringClass()->GetClassLoader();
}

static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
                            const char* sig, bool is_static)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  Class* c = soa.Decode<Class*>(jni_class);
  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
    return NULL;
  }

  Field* field = NULL;
  Class* field_type;
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  if (sig[1] != '\0') {
    ClassLoader* cl = GetClassLoader(soa.Self());
    field_type = class_linker->FindClass(sig, cl);
  } else {
    field_type = class_linker->FindPrimitiveClass(*sig);
  }
  if (field_type == NULL) {
    // Failed to find type from the signature of the field.
    DCHECK(soa.Self()->IsExceptionPending());
    soa.Self()->ClearException();
    soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
        "no type \"%s\" found and so no field \"%s\" could be found in class "
        "\"%s\" or its superclasses", sig, name, ClassHelper(c).GetDescriptor());
    return NULL;
  }
  if (is_static) {
    field = c->FindStaticField(name, ClassHelper(field_type).GetDescriptor());
  } else {
    field = c->FindInstanceField(name, ClassHelper(field_type).GetDescriptor());
  }
  if (field == NULL) {
    soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
        "no \"%s\" field \"%s\" in class \"%s\" or its superclasses", sig,
        name, ClassHelper(c).GetDescriptor());
    return NULL;
  }
  return soa.EncodeField(field);
}

static void PinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  JavaVMExt* vm = soa.Vm();
  MutexLock mu(vm->pins_lock);
  vm->pin_table.Add(array);
}

static void UnpinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  JavaVMExt* vm = soa.Vm();
  MutexLock mu(vm->pins_lock);
  vm->pin_table.Remove(array);
}

static void ThrowAIOOBE(ScopedObjectAccess& soa, Array* array, jsize start,
                        jsize length, const char* identifier)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  std::string type(PrettyTypeOf(array));
  soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
      "%s offset=%d length=%d %s.length=%d",
      type.c_str(), start, length, identifier, array->GetLength());
}

static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
                        jsize array_length)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
      "offset=%d length=%d string.length()=%d", start, length, array_length);
}

int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
    LOCKS_EXCLUDED(Locks::mutator_lock_) {
  ScopedObjectAccess soa(env);

  // Turn the const char* into a java.lang.String.
  ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
  if (msg != NULL && s.get() == NULL) {
    return JNI_ERR;
  }

  // Choose an appropriate constructor and set up the arguments.
  jvalue args[2];
  const char* signature;
  if (msg == NULL && cause == NULL) {
    signature = "()V";
  } else if (msg != NULL && cause == NULL) {
    signature = "(Ljava/lang/String;)V";
    args[0].l = s.get();
  } else if (msg == NULL && cause != NULL) {
    signature = "(Ljava/lang/Throwable;)V";
    args[0].l = cause;
  } else {
    signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
    args[0].l = s.get();
    args[1].l = cause;
  }
  jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
  if (mid == NULL) {
    LOG(ERROR) << "No <init>" << signature << " in "
        << PrettyClass(soa.Decode<Class*>(exception_class));
    return JNI_ERR;
  }

  ScopedLocalRef<jthrowable> exception(env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
  if (exception.get() == NULL) {
    return JNI_ERR;
  }

  soa.Self()->SetException(soa.Decode<Throwable*>(exception.get()));

  return JNI_OK;
}

static jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
  if (vm == NULL || p_env == NULL) {
    return JNI_ERR;
  }

  // Return immediately if we're already attached.
  Thread* self = Thread::Current();
  if (self != NULL) {
    *p_env = self->GetJniEnv();
    return JNI_OK;
  }

  Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->runtime;

  // No threads allowed in zygote mode.
  if (runtime->IsZygote()) {
    LOG(ERROR) << "Attempt to attach a thread in the zygote";
    return JNI_ERR;
  }

  JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args);
  const char* thread_name = NULL;
  jobject thread_group = NULL;
  if (args != NULL) {
    CHECK_GE(args->version, JNI_VERSION_1_2);
    thread_name = args->name;
    thread_group = args->group;
  }

  runtime->AttachCurrentThread(thread_name, as_daemon, thread_group);
  *p_env = Thread::Current()->GetJniEnv();
  return JNI_OK;
}

class SharedLibrary {
 public:
  SharedLibrary(const std::string& path, void* handle, Object* class_loader)
      : path_(path),
        handle_(handle),
        class_loader_(class_loader),
        jni_on_load_lock_("JNI_OnLoad lock"),
        jni_on_load_cond_("JNI_OnLoad condition variable"),
        jni_on_load_thread_id_(Thread::Current()->GetThinLockId()),
        jni_on_load_result_(kPending) {
  }

  Object* GetClassLoader() {
    return class_loader_;
  }

  std::string GetPath() {
    return path_;
  }

  /*
   * Check the result of an earlier call to JNI_OnLoad on this library.
   * If the call has not yet finished in another thread, wait for it.
   */
  bool CheckOnLoadResult()
      LOCKS_EXCLUDED(jni_on_load_lock_)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    Thread* self = Thread::Current();
    self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
    bool okay;
    {
      MutexLock mu(jni_on_load_lock_);

      if (jni_on_load_thread_id_ == self->GetThinLockId()) {
        // Check this so we don't end up waiting for ourselves.  We need to return "true" so the
        // caller can continue.
        LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\"";
        okay = true;
      } else {
        while (jni_on_load_result_ == kPending) {
          VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]";
          jni_on_load_cond_.Wait(self, jni_on_load_lock_);
        }

        okay = (jni_on_load_result_ == kOkay);
        VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" "
            << (okay ? "succeeded" : "failed") << "]";
      }
    }
    self->TransitionFromSuspendedToRunnable();
    return okay;
  }

  void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) {
    MutexLock mu(jni_on_load_lock_);

    jni_on_load_result_ = result ? kOkay : kFailed;
    jni_on_load_thread_id_ = 0;

    // Broadcast a wakeup to anybody sleeping on the condition variable.
    jni_on_load_cond_.Broadcast();
  }

  void* FindSymbol(const std::string& symbol_name) {
    return dlsym(handle_, symbol_name.c_str());
  }

 private:
  enum JNI_OnLoadState {
    kPending,
    kFailed,
    kOkay,
  };

  // Path to library "/system/lib/libjni.so".
  std::string path_;

  // The void* returned by dlopen(3).
  void* handle_;

  // The ClassLoader this library is associated with.
  Object* class_loader_;

  // Guards remaining items.
  Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
  // Wait for JNI_OnLoad in other thread.
  ConditionVariable jni_on_load_cond_;
  // Recursive invocation guard.
  uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
  // Result of earlier JNI_OnLoad call.
  JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
};

// This exists mainly to keep implementation details out of the header file.
class Libraries {
 public:
  Libraries() {
  }

  ~Libraries() {
    STLDeleteValues(&libraries_);
  }

  void Dump(std::ostream& os) const {
    bool first = true;
    for (It it = libraries_.begin(); it != libraries_.end(); ++it) {
      if (!first) {
        os << ' ';
      }
      first = false;
      os << it->first;
    }
  }

  size_t size() const {
    return libraries_.size();
  }

  SharedLibrary* Get(const std::string& path) {
    It it = libraries_.find(path);
    return (it == libraries_.end()) ? NULL : it->second;
  }

  void Put(const std::string& path, SharedLibrary* library) {
    libraries_.Put(path, library);
  }

  // See section 11.3 "Linking Native Methods" of the JNI spec.
  void* FindNativeMethod(const AbstractMethod* m, std::string& detail)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    std::string jni_short_name(JniShortName(m));
    std::string jni_long_name(JniLongName(m));
    const ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader();
    for (It it = libraries_.begin(); it != libraries_.end(); ++it) {
      SharedLibrary* library = it->second;
      if (library->GetClassLoader() != declaring_class_loader) {
        // We only search libraries loaded by the appropriate ClassLoader.
        continue;
      }
      // Try the short name then the long name...
      void* fn = library->FindSymbol(jni_short_name);
      if (fn == NULL) {
        fn = library->FindSymbol(jni_long_name);
      }
      if (fn != NULL) {
        VLOG(jni) << "[Found native code for " << PrettyMethod(m)
                  << " in \"" << library->GetPath() << "\"]";
        return fn;
      }
    }
    detail += "No implementation found for ";
    detail += PrettyMethod(m);
    detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
    LOG(ERROR) << detail;
    return NULL;
  }

 private:
  typedef SafeMap<std::string, SharedLibrary*>::const_iterator It; // TODO: C++0x auto

  SafeMap<std::string, SharedLibrary*> libraries_;
};

JValue InvokeWithJValues(const ScopedObjectAccess& soa, jobject obj, jmethodID mid,
                         jvalue* args) {
  Object* receiver = soa.Decode<Object*>(obj);
  AbstractMethod* method = soa.DecodeMethod(mid);
  ArgArray arg_array(method);
  arg_array.BuildArgArray(soa, args);
  return InvokeWithArgArray(soa, receiver, method, arg_array.get());
}

JValue InvokeWithJValues(const ScopedObjectAccess& soa, Object* receiver, AbstractMethod* m,
                         JValue* args)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  return InvokeWithArgArray(soa, receiver, m, args);
}

class JNI {
 public:
  static jint GetVersion(JNIEnv*) {
    return JNI_VERSION_1_6;
  }

  static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
    LOG(WARNING) << "JNI DefineClass is not supported";
    return NULL;
  }

  static jclass FindClass(JNIEnv* env, const char* name) {
    ScopedObjectAccess soa(env);
    Runtime* runtime = Runtime::Current();
    ClassLinker* class_linker = runtime->GetClassLinker();
    std::string descriptor(NormalizeJniClassDescriptor(name));
    Class* c = NULL;
    if (runtime->IsStarted()) {
      ClassLoader* cl = GetClassLoader(soa.Self());
      c = class_linker->FindClass(descriptor.c_str(), cl);
    } else {
      c = class_linker->FindSystemClass(descriptor.c_str());
    }
    return soa.AddLocalReference<jclass>(c);
  }

  static jmethodID FromReflectedMethod(JNIEnv* env, jobject java_method) {
    ScopedObjectAccess soa(env);
    AbstractMethod* method = soa.Decode<AbstractMethod*>(java_method);
    return soa.EncodeMethod(method);
  }

  static jfieldID FromReflectedField(JNIEnv* env, jobject java_field) {
    ScopedObjectAccess soa(env);
    Field* field = soa.Decode<Field*>(java_field);
    return soa.EncodeField(field);
  }

  static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
    ScopedObjectAccess soa(env);
    AbstractMethod* method = soa.DecodeMethod(mid);
    return soa.AddLocalReference<jobject>(method);
  }

  static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
    ScopedObjectAccess soa(env);
    Field* field = soa.DecodeField(fid);
    return soa.AddLocalReference<jobject>(field);
  }

  static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
    ScopedObjectAccess soa(env);
    Object* o = soa.Decode<Object*>(java_object);
    return soa.AddLocalReference<jclass>(o->GetClass());
  }

  static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
    ScopedObjectAccess soa(env);
    Class* c = soa.Decode<Class*>(java_class);
    return soa.AddLocalReference<jclass>(c->GetSuperClass());
  }

  static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
    ScopedObjectAccess soa(env);
    Class* c1 = soa.Decode<Class*>(java_class1);
    Class* c2 = soa.Decode<Class*>(java_class2);
    return c1->IsAssignableFrom(c2) ? JNI_TRUE : JNI_FALSE;
  }

  static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
    ScopedObjectAccess soa(env);
    CHECK_NE(static_cast<jclass>(NULL), java_class); // TODO: ReportJniError
    if (jobj == NULL) {
      // Note: JNI is different from regular Java instanceof in this respect
      return JNI_TRUE;
    } else {
      Object* obj = soa.Decode<Object*>(jobj);
      Class* c = soa.Decode<Class*>(java_class);
      return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
    }
  }

  static jint Throw(JNIEnv* env, jthrowable java_exception) {
    ScopedObjectAccess soa(env);
    Throwable* exception = soa.Decode<Throwable*>(java_exception);
    if (exception == NULL) {
      return JNI_ERR;
    }
    soa.Self()->SetException(exception);
    return JNI_OK;
  }

  static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
    return ThrowNewException(env, c, msg, NULL);
  }

  static jboolean ExceptionCheck(JNIEnv* env) {
    ScopedObjectAccess soa(env);
    return soa.Self()->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
  }

  static void ExceptionClear(JNIEnv* env) {
    ScopedObjectAccess soa(env);
    soa.Self()->ClearException();
  }

  static void ExceptionDescribe(JNIEnv* env) {
    ScopedObjectAccess soa(env);

    Thread* self = soa.Self();
    Throwable* original_exception = self->GetException();
    self->ClearException();

    ScopedLocalRef<jthrowable> exception(env, soa.AddLocalReference<jthrowable>(original_exception));
    ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
    jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
    if (mid == NULL) {
      LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
                   << PrettyTypeOf(original_exception);
    } else {
      env->CallVoidMethod(exception.get(), mid);
      if (self->IsExceptionPending()) {
        LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(self->GetException())
                     << " thrown while calling printStackTrace";
        self->ClearException();
      }
    }

    self->SetException(original_exception);
  }

  static jthrowable ExceptionOccurred(JNIEnv* env) {
    ScopedObjectAccess soa(env);
    Object* exception = soa.Self()->GetException();
    return soa.AddLocalReference<jthrowable>(exception);
  }

  static void FatalError(JNIEnv*, const char* msg) {
    LOG(FATAL) << "JNI FatalError called: " << msg;
  }

  static jint PushLocalFrame(JNIEnv* env, jint capacity) {
    ScopedObjectAccess soa(env);
    if (EnsureLocalCapacity(soa, capacity, "PushLocalFrame") != JNI_OK) {
      return JNI_ERR;
    }
    soa.Env()->PushFrame(capacity);
    return JNI_OK;
  }

  static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
    ScopedObjectAccess soa(env);
    Object* survivor = soa.Decode<Object*>(java_survivor);
    soa.Env()->PopFrame();
    return soa.AddLocalReference<jobject>(survivor);
  }

  static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
    ScopedObjectAccess soa(env);
    return EnsureLocalCapacity(soa, desired_capacity, "EnsureLocalCapacity");
  }

  static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
    if (obj == NULL) {
      return NULL;
    }
    ScopedObjectAccess soa(env);
    JavaVMExt* vm = soa.Vm();
    IndirectReferenceTable& globals = vm->globals;
    Object* decoded_obj = soa.Decode<Object*>(obj);
    MutexLock mu(vm->globals_lock);
    IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
    return reinterpret_cast<jobject>(ref);
  }

  static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
    if (obj == NULL) {
      return;
    }
    ScopedObjectAccess soa(env);
    JavaVMExt* vm = soa.Vm();
    IndirectReferenceTable& globals = vm->globals;
    MutexLock mu(vm->globals_lock);

    if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
      LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
                   << "failed to find entry";
    }
  }

  static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
    ScopedObjectAccess soa(env);
    return AddWeakGlobalReference(soa, soa.Decode<Object*>(obj));
  }

  static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
    if (obj == NULL) {
      return;
    }
    ScopedObjectAccess soa(env);
    JavaVMExt* vm = soa.Vm();
    IndirectReferenceTable& weak_globals = vm->weak_globals;
    MutexLock mu(vm->weak_globals_lock);

    if (!weak_globals.Remove(IRT_FIRST_SEGMENT, obj)) {
      LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
                   << "failed to find entry";
    }
  }

  static jobject NewLocalRef(JNIEnv* env, jobject obj) {
    if (obj == NULL) {
      return NULL;
    }
    ScopedObjectAccess soa(env);
    IndirectReferenceTable& locals = soa.Env()->locals;

    uint32_t cookie = soa.Env()->local_ref_cookie;
    IndirectRef ref = locals.Add(cookie, soa.Decode<Object*>(obj));
    return reinterpret_cast<jobject>(ref);
  }

  static void DeleteLocalRef(JNIEnv* env, jobject obj) {
    if (obj == NULL) {
      return;
    }
    ScopedObjectAccess soa(env);
    IndirectReferenceTable& locals = soa.Env()->locals;

    uint32_t cookie = soa.Env()->local_ref_cookie;
    if (!locals.Remove(cookie, obj)) {
      // Attempting to delete a local reference that is not in the
      // topmost local reference frame is a no-op.  DeleteLocalRef returns
      // void and doesn't throw any exceptions, but we should probably
      // complain about it so the user will notice that things aren't
      // going quite the way they expect.
      LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
                   << "failed to find entry";
    }
  }

  static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
    ScopedObjectAccess soa(env);
    return (soa.Decode<Object*>(obj1) == soa.Decode<Object*>(obj2))
        ? JNI_TRUE : JNI_FALSE;
  }

  static jobject AllocObject(JNIEnv* env, jclass java_class) {
    ScopedObjectAccess soa(env);
    Class* c = soa.Decode<Class*>(java_class);
    if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
      return NULL;
    }
    return soa.AddLocalReference<jobject>(c->AllocObject());
  }

  static jobject NewObject(JNIEnv* env, jclass c, jmethodID mid, ...) {
    va_list args;
    va_start(args, mid);
    jobject result = NewObjectV(env, c, mid, args);
    va_end(args);
    return result;
  }

  static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    Class* c = soa.Decode<Class*>(java_class);
    if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
      return NULL;
    }
    Object* result = c->AllocObject();
    if (result == NULL) {
      return NULL;
    }
    jobject local_result = soa.AddLocalReference<jobject>(result);
    CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
    if (!soa.Self()->IsExceptionPending()) {
      return local_result;
    } else {
      return NULL;
    }
  }

  static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    Class* c = soa.Decode<Class*>(java_class);
    if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
      return NULL;
    }
    Object* result = c->AllocObject();
    if (result == NULL) {
      return NULL;
    }
    jobject local_result = soa.AddLocalReference<jobjectArray>(result);
    CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
    if (!soa.Self()->IsExceptionPending()) {
      return local_result;
    } else {
      return NULL;
    }
  }

  static jmethodID GetMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
    ScopedObjectAccess soa(env);
    return FindMethodID(soa, c, name, sig, false);
  }

  static jmethodID GetStaticMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
    ScopedObjectAccess soa(env);
    return FindMethodID(soa, c, name, sig, true);
  }

  static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return soa.AddLocalReference<jobject>(result.GetL());
  }

  static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
    return soa.AddLocalReference<jobject>(result.GetL());
  }

  static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
    return soa.AddLocalReference<jobject>(result.GetL());
  }

  static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetZ();
  }

  static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
  }

  static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
  }

  static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    ScopedObjectAccess soa(env);
    va_list ap;
    va_start(ap, mid);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetB();
  }

  static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
  }

  static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
  }

  static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetC();
  }

  static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
  }

  static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
  }

  static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetD();
  }

  static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
  }

  static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
  }

  static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    ScopedObjectAccess soa(env);
    va_list ap;
    va_start(ap, mid);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetF();
  }

  static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
  }

  static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
  }

  static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetI();
  }

  static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
  }

  static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
  }

  static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetJ();
  }

  static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
  }

  static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
  }

  static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetS();
  }

  static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
  }

  static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
  }

  static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
    va_end(ap);
  }

  static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
  }

  static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
  }

  static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
    va_end(ap);
    return local_result;
  }

  static jobject CallNonvirtualObjectMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, args));
    return soa.AddLocalReference<jobject>(result.GetL());
  }

  static jobject CallNonvirtualObjectMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithJValues(soa, obj, mid, args));
    return soa.AddLocalReference<jobject>(result.GetL());
  }

  static jboolean CallNonvirtualBooleanMethod(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetZ();
  }

  static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
  }

  static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, obj, mid, args).GetZ();
  }

  static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetB();
  }

  static jbyte CallNonvirtualByteMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, obj, mid, args).GetB();
  }

  static jbyte CallNonvirtualByteMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, obj, mid, args).GetB();
  }

  static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    ScopedObjectAccess soa(env);
    va_list ap;
    va_start(ap, mid);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetC();
  }

  static jchar CallNonvirtualCharMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, obj, mid, args).GetC();
  }

  static jchar CallNonvirtualCharMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, obj, mid, args).GetC();
  }

  static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetS();
  }

  static jshort CallNonvirtualShortMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, obj, mid, args).GetS();
  }

  static jshort CallNonvirtualShortMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, obj, mid, args).GetS();
  }

  static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetI();
  }

  static jint CallNonvirtualIntMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, obj, mid, args).GetI();
  }

  static jint CallNonvirtualIntMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, obj, mid, args).GetI();
  }

  static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetJ();
  }

  static jlong CallNonvirtualLongMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
  }

  static jlong CallNonvirtualLongMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, obj, mid, args).GetJ();
  }

  static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetF();
  }

  static jfloat CallNonvirtualFloatMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, obj, mid, args).GetF();
  }

  static jfloat CallNonvirtualFloatMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, obj, mid, args).GetF();
  }

  static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    va_end(ap);
    return result.GetD();
  }

  static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, obj, mid, args).GetD();
  }

  static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, obj, mid, args).GetD();
  }

  static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    InvokeWithVarArgs(soa, obj, mid, ap);
    va_end(ap);
  }

  static void CallNonvirtualVoidMethodV(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    InvokeWithVarArgs(soa, obj, mid, args);
  }

  static void CallNonvirtualVoidMethodA(JNIEnv* env,
      jobject obj, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    InvokeWithJValues(soa, obj, mid, args);
  }

  static jfieldID GetFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) {
    ScopedObjectAccess soa(env);
    return FindFieldID(soa, c, name, sig, false);
  }


  static jfieldID GetStaticFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) {
    ScopedObjectAccess soa(env);
    return FindFieldID(soa, c, name, sig, true);
  }

  static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
    ScopedObjectAccess soa(env);
    Object* o = soa.Decode<Object*>(obj);
    Field* f = soa.DecodeField(fid);
    return soa.AddLocalReference<jobject>(f->GetObject(o));
  }

  static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
    ScopedObjectAccess soa(env);
    Field* f = soa.DecodeField(fid);
    return soa.AddLocalReference<jobject>(f->GetObject(NULL));
  }

  static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
    ScopedObjectAccess soa(env);
    Object* o = soa.Decode<Object*>(java_object);
    Object* v = soa.Decode<Object*>(java_value);
    Field* f = soa.DecodeField(fid);
    f->SetObject(o, v);
  }

  static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
    ScopedObjectAccess soa(env);
    Object* v = soa.Decode<Object*>(java_value);
    Field* f = soa.DecodeField(fid);
    f->SetObject(NULL, v);
  }

#define GET_PRIMITIVE_FIELD(fn, instance) \
  ScopedObjectAccess soa(env); \
  Object* o = soa.Decode<Object*>(instance); \
  Field* f = soa.DecodeField(fid); \
  return f->fn(o)

#define SET_PRIMITIVE_FIELD(fn, instance, value) \
  ScopedObjectAccess soa(env); \
  Object* o = soa.Decode<Object*>(instance); \
  Field* f = soa.DecodeField(fid); \
  f->fn(o, value)

  static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetBoolean, obj);
  }

  static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetByte, obj);
  }

  static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetChar, obj);
  }

  static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetShort, obj);
  }

  static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetInt, obj);
  }

  static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetLong, obj);
  }

  static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetFloat, obj);
  }

  static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetDouble, obj);
  }

  static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetBoolean, NULL);
  }

  static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetByte, NULL);
  }

  static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetChar, NULL);
  }

  static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetShort, NULL);
  }

  static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetInt, NULL);
  }

  static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetLong, NULL);
  }

  static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetFloat, NULL);
  }

  static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
    GET_PRIMITIVE_FIELD(GetDouble, NULL);
  }

  static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
    SET_PRIMITIVE_FIELD(SetBoolean, obj, v);
  }

  static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
    SET_PRIMITIVE_FIELD(SetByte, obj, v);
  }

  static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
    SET_PRIMITIVE_FIELD(SetChar, obj, v);
  }

  static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
    SET_PRIMITIVE_FIELD(SetFloat, obj, v);
  }

  static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
    SET_PRIMITIVE_FIELD(SetDouble, obj, v);
  }

  static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
    SET_PRIMITIVE_FIELD(SetInt, obj, v);
  }

  static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
    SET_PRIMITIVE_FIELD(SetLong, obj, v);
  }

  static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
    SET_PRIMITIVE_FIELD(SetShort, obj, v);
  }

  static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
    SET_PRIMITIVE_FIELD(SetBoolean, NULL, v);
  }

  static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
    SET_PRIMITIVE_FIELD(SetByte, NULL, v);
  }

  static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
    SET_PRIMITIVE_FIELD(SetChar, NULL, v);
  }

  static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
    SET_PRIMITIVE_FIELD(SetFloat, NULL, v);
  }

  static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
    SET_PRIMITIVE_FIELD(SetDouble, NULL, v);
  }

  static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
    SET_PRIMITIVE_FIELD(SetInt, NULL, v);
  }

  static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
    SET_PRIMITIVE_FIELD(SetLong, NULL, v);
  }

  static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
    SET_PRIMITIVE_FIELD(SetShort, NULL, v);
  }

  static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
    va_end(ap);
    return local_result;
  }

  static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, args));
    return soa.AddLocalReference<jobject>(result.GetL());
  }

  static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithJValues(soa, NULL, mid, args));
    return soa.AddLocalReference<jobject>(result.GetL());
  }

  static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    va_end(ap);
    return result.GetZ();
  }

  static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, NULL, mid, args).GetZ();
  }

  static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, NULL, mid, args).GetZ();
  }

  static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    va_end(ap);
    return result.GetB();
  }

  static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, NULL, mid, args).GetB();
  }

  static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, NULL, mid, args).GetB();
  }

  static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    va_end(ap);
    return result.GetC();
  }

  static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, NULL, mid, args).GetC();
  }

  static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, NULL, mid, args).GetC();
  }

  static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    va_end(ap);
    return result.GetS();
  }

  static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, NULL, mid, args).GetS();
  }

  static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, NULL, mid, args).GetS();
  }

  static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    va_end(ap);
    return result.GetI();
  }

  static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, NULL, mid, args).GetI();
  }

  static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, NULL, mid, args).GetI();
  }

  static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    va_end(ap);
    return result.GetJ();
  }

  static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, NULL, mid, args).GetJ();
  }

  static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, NULL, mid, args).GetJ();
  }

  static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    va_end(ap);
    return result.GetF();
  }

  static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, NULL, mid, args).GetF();
  }

  static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, NULL, mid, args).GetF();
  }

  static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
    va_end(ap);
    return result.GetD();
  }

  static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    return InvokeWithVarArgs(soa, NULL, mid, args).GetD();
  }

  static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    return InvokeWithJValues(soa, NULL, mid, args).GetD();
  }

  static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
    va_list ap;
    va_start(ap, mid);
    ScopedObjectAccess soa(env);
    InvokeWithVarArgs(soa, NULL, mid, ap);
    va_end(ap);
  }

  static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
    ScopedObjectAccess soa(env);
    InvokeWithVarArgs(soa, NULL, mid, args);
  }

  static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
    ScopedObjectAccess soa(env);
    InvokeWithJValues(soa, NULL, mid, args);
  }

  static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
    ScopedObjectAccess soa(env);
    String* result = String::AllocFromUtf16(char_count, chars);
    return soa.AddLocalReference<jstring>(result);
  }

  static jstring NewStringUTF(JNIEnv* env, const char* utf) {
    if (utf == NULL) {
      return NULL;
    }
    ScopedObjectAccess soa(env);
    String* result = String::AllocFromModifiedUtf8(utf);
    return soa.AddLocalReference<jstring>(result);
  }

  static jsize GetStringLength(JNIEnv* env, jstring java_string) {
    ScopedObjectAccess soa(env);
    return soa.Decode<String*>(java_string)->GetLength();
  }

  static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
    ScopedObjectAccess soa(env);
    return soa.Decode<String*>(java_string)->GetUtfLength();
  }

  static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length, jchar* buf) {
    ScopedObjectAccess soa(env);
    String* s = soa.Decode<String*>(java_string);
    if (start < 0 || length < 0 || start + length > s->GetLength()) {
      ThrowSIOOBE(soa, start, length, s->GetLength());
    } else {
      const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
      memcpy(buf, chars + start, length * sizeof(jchar));
    }
  }

  static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length, char* buf) {
    ScopedObjectAccess soa(env);
    String* s = soa.Decode<String*>(java_string);
    if (start < 0 || length < 0 || start + length > s->GetLength()) {
      ThrowSIOOBE(soa, start, length, s->GetLength());
    } else {
      const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
      ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
    }
  }

  static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    String* s = soa.Decode<String*>(java_string);
    const CharArray* chars = s->GetCharArray();
    PinPrimitiveArray(soa, chars);
    if (is_copy != NULL) {
      *is_copy = JNI_FALSE;
    }
    return chars->GetData() + s->GetOffset();
  }

  static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar*) {
    ScopedObjectAccess soa(env);
    UnpinPrimitiveArray(soa, soa.Decode<String*>(java_string)->GetCharArray());
  }

  static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetStringChars(env, java_string, is_copy);
  }

  static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
    ScopedObjectAccess soa(env);
    return ReleaseStringChars(env, java_string, chars);
  }

  static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    if (java_string == NULL) {
      return NULL;
    }
    if (is_copy != NULL) {
      *is_copy = JNI_TRUE;
    }
    String* s = soa.Decode<String*>(java_string);
    size_t byte_count = s->GetUtfLength();
    char* bytes = new char[byte_count + 1];
    CHECK(bytes != NULL); // bionic aborts anyway.
    const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset();
    ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
    bytes[byte_count] = '\0';
    return bytes;
  }

  static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
    ScopedObjectAccess soa(env);
    delete[] chars;
  }

  static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
    ScopedObjectAccess soa(env);
    Object* obj = soa.Decode<Object*>(java_array);
    CHECK(obj->IsArrayInstance()); // TODO: ReportJniError
    Array* array = obj->AsArray();
    return array->GetLength();
  }

  static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
    ScopedObjectAccess soa(env);
    ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array);
    return soa.AddLocalReference<jobject>(array->Get(index));
  }

  static void SetObjectArrayElement(JNIEnv* env,
      jobjectArray java_array, jsize index, jobject java_value) {
    ScopedObjectAccess soa(env);
    ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array);
    Object* value = soa.Decode<Object*>(java_value);
    array->Set(index, value);
  }

  static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
    ScopedObjectAccess soa(env);
    return NewPrimitiveArray<jbooleanArray, BooleanArray>(soa, length);
  }

  static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
    ScopedObjectAccess soa(env);
    return NewPrimitiveArray<jbyteArray, ByteArray>(soa, length);
  }

  static jcharArray NewCharArray(JNIEnv* env, jsize length) {
    ScopedObjectAccess soa(env);
    return NewPrimitiveArray<jcharArray, CharArray>(soa, length);
  }

  static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
    ScopedObjectAccess soa(env);
    return NewPrimitiveArray<jdoubleArray, DoubleArray>(soa, length);
  }

  static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
    ScopedObjectAccess soa(env);
    return NewPrimitiveArray<jfloatArray, FloatArray>(soa, length);
  }

  static jintArray NewIntArray(JNIEnv* env, jsize length) {
    ScopedObjectAccess soa(env);
    return NewPrimitiveArray<jintArray, IntArray>(soa, length);
  }

  static jlongArray NewLongArray(JNIEnv* env, jsize length) {
    ScopedObjectAccess soa(env);
    return NewPrimitiveArray<jlongArray, LongArray>(soa, length);
  }

  static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass, jobject initial_element) {
    ScopedObjectAccess soa(env);
    CHECK_GE(length, 0); // TODO: ReportJniError

    // Compute the array class corresponding to the given element class.
    Class* element_class = soa.Decode<Class*>(element_jclass);
    std::string descriptor;
    descriptor += "[";
    descriptor += ClassHelper(element_class).GetDescriptor();

    // Find the class.
    ScopedLocalRef<jclass> java_array_class(env, FindClass(env, descriptor.c_str()));
    if (java_array_class.get() == NULL) {
      return NULL;
    }

    // Allocate and initialize if necessary.
    Class* array_class = soa.Decode<Class*>(java_array_class.get());
    ObjectArray<Object>* result = ObjectArray<Object>::Alloc(array_class, length);
    if (initial_element != NULL) {
      Object* initial_object = soa.Decode<Object*>(initial_element);
      for (jsize i = 0; i < length; ++i) {
        result->Set(i, initial_object);
      }
    }
    return soa.AddLocalReference<jobjectArray>(result);
  }

  static jshortArray NewShortArray(JNIEnv* env, jsize length) {
    ScopedObjectAccess soa(env);
    return NewPrimitiveArray<jshortArray, ShortArray>(soa, length);
  }

  static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    Array* array = soa.Decode<Array*>(java_array);
    PinPrimitiveArray(soa, array);
    if (is_copy != NULL) {
      *is_copy = JNI_FALSE;
    }
    return array->GetRawData(array->GetClass()->GetComponentSize());
  }

  static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetPrimitiveArray<jbooleanArray, jboolean*, BooleanArray>(soa, array, is_copy);
  }

  static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetPrimitiveArray<jbyteArray, jbyte*, ByteArray>(soa, array, is_copy);
  }

  static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetPrimitiveArray<jcharArray, jchar*, CharArray>(soa, array, is_copy);
  }

  static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetPrimitiveArray<jdoubleArray, jdouble*, DoubleArray>(soa, array, is_copy);
  }

  static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetPrimitiveArray<jfloatArray, jfloat*, FloatArray>(soa, array, is_copy);
  }

  static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetPrimitiveArray<jintArray, jint*, IntArray>(soa, array, is_copy);
  }

  static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetPrimitiveArray<jlongArray, jlong*, LongArray>(soa, array, is_copy);
  }

  static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
    ScopedObjectAccess soa(env);
    return GetPrimitiveArray<jshortArray, jshort*, ShortArray>(soa, array, is_copy);
  }

  static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort*, jint mode) {
    ScopedObjectAccess soa(env);
    ReleasePrimitiveArray(soa, array, mode);
  }

  static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length, jboolean* buf) {
    ScopedObjectAccess soa(env);
    GetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf);
  }

  static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length, jbyte* buf) {
    ScopedObjectAccess soa(env);
    GetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf);
  }

  static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length, jchar* buf) {
    ScopedObjectAccess soa(env);
    GetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf);
  }

  static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length, jdouble* buf) {
    ScopedObjectAccess soa(env);
    GetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf);
  }

  static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length, jfloat* buf) {
    ScopedObjectAccess soa(env);
    GetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf);
  }

  static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length, jint* buf) {
    ScopedObjectAccess soa(env);
    GetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf);
  }

  static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length, jlong* buf) {
    ScopedObjectAccess soa(env);
    GetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf);
  }

  static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length, jshort* buf) {
    ScopedObjectAccess soa(env);
    GetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf);
  }

  static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length, const jboolean* buf) {
    ScopedObjectAccess soa(env);
    SetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf);
  }

  static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length, const jbyte* buf) {
    ScopedObjectAccess soa(env);
    SetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf);
  }

  static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length, const jchar* buf) {
    ScopedObjectAccess soa(env);
    SetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf);
  }

  static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length, const jdouble* buf) {
    ScopedObjectAccess soa(env);
    SetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf);
  }

  static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length, const jfloat* buf) {
    ScopedObjectAccess soa(env);
    SetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf);
  }

  static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length, const jint* buf) {
    ScopedObjectAccess soa(env);
    SetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf);
  }

  static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length, const jlong* buf) {
    ScopedObjectAccess soa(env);
    SetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf);
  }

  static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length, const jshort* buf) {
    ScopedObjectAccess soa(env);
    SetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf);
  }

  static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods, jint method_count) {
    ScopedObjectAccess soa(env);
    Class* c = soa.Decode<Class*>(java_class);

    for (int i = 0; i < method_count; i++) {
      const char* name = methods[i].name;
      const char* sig = methods[i].signature;

      if (*sig == '!') {
        // TODO: fast jni. it's too noisy to log all these.
        ++sig;
      }

      AbstractMethod* m = c->FindDirectMethod(name, sig);
      if (m == NULL) {
        m = c->FindVirtualMethod(name, sig);
      }
      if (m == NULL) {
        LOG(INFO) << "Failed to register native method " << name << sig;
        ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
        return JNI_ERR;
      } else if (!m->IsNative()) {
        LOG(INFO) << "Failed to register non-native method " << name << sig << " as native";
        ThrowNoSuchMethodError(soa, c, name, sig, "native");
        return JNI_ERR;
      }

      VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";

      m->RegisterNative(soa.Self(), methods[i].fnPtr);
    }
    return JNI_OK;
  }

  static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
    ScopedObjectAccess soa(env);
    Class* c = soa.Decode<Class*>(java_class);

    VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";

    for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
      AbstractMethod* m = c->GetDirectMethod(i);
      if (m->IsNative()) {
        m->UnregisterNative(soa.Self());
      }
    }
    for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
      AbstractMethod* m = c->GetVirtualMethod(i);
      if (m->IsNative()) {
        m->UnregisterNative(soa.Self());
      }
    }

    return JNI_OK;
  }

  static jint MonitorEnter(JNIEnv* env, jobject java_object)
      EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) {
    ScopedObjectAccess soa(env);
    Object* o = soa.Decode<Object*>(java_object);
    o->MonitorEnter(soa.Self());
    if (soa.Self()->IsExceptionPending()) {
      return JNI_ERR;
    }
    soa.Env()->monitors.Add(o);
    return JNI_OK;
  }

  static jint MonitorExit(JNIEnv* env, jobject java_object)
      UNLOCK_FUNCTION(monitor_lock_) {
    ScopedObjectAccess soa(env);
    Object* o = soa.Decode<Object*>(java_object);
    o->MonitorExit(soa.Self());
    if (soa.Self()->IsExceptionPending()) {
      return JNI_ERR;
    }
    soa.Env()->monitors.Remove(o);
    return JNI_OK;
  }

  static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
    ScopedObjectAccess soa(env);
    Runtime* runtime = Runtime::Current();
    if (runtime != NULL) {
      *vm = runtime->GetJavaVM();
    } else {
      *vm = NULL;
    }
    return (*vm != NULL) ? JNI_OK : JNI_ERR;
  }

  static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
    ScopedObjectAccess soa(env);

    // The address may not be NULL, and the capacity must be > 0.
    CHECK(address != NULL); // TODO: ReportJniError
    CHECK_GT(capacity, 0); // TODO: ReportJniError

    // At the moment, the Java side is limited to 32 bisoa.
    CHECK_LE(reinterpret_cast<uintptr_t>(address), 0xffffffff);
    CHECK_LE(capacity, 0xffffffff);
    jint address_arg = reinterpret_cast<jint>(address);
    jint capacity_arg = static_cast<jint>(capacity);

    jobject result = env->NewObject(WellKnownClasses::java_nio_ReadWriteDirectByteBuffer,
                                    WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_init,
                                    address_arg, capacity_arg);
    return soa.Self()->IsExceptionPending() ? NULL : result;
  }

  static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
    ScopedObjectAccess soa(env);
    return reinterpret_cast<void*>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_effectiveDirectAddress));
  }

  static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
    ScopedObjectAccess soa(env);
    return static_cast<jlong>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_capacity));
  }

  static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
    ScopedObjectAccess soa(env);

    CHECK(java_object != NULL); // TODO: ReportJniError

    // Do we definitely know what kind of reference this is?
    IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
    IndirectRefKind kind = GetIndirectRefKind(ref);
    switch (kind) {
    case kLocal:
      if (soa.Env()->locals.Get(ref) != kInvalidIndirectRefObject) {
        return JNILocalRefType;
      }
      return JNIInvalidRefType;
    case kGlobal:
      return JNIGlobalRefType;
    case kWeakGlobal:
      return JNIWeakGlobalRefType;
    case kSirtOrInvalid:
      // Is it in a stack IRT?
      if (soa.Self()->SirtContains(java_object)) {
        return JNILocalRefType;
      }

      if (!soa.Vm()->work_around_app_jni_bugs) {
        return JNIInvalidRefType;
      }

      // If we're handing out direct pointers, check whether it's a direct pointer
      // to a local reference.
      if (soa.Decode<Object*>(java_object) == reinterpret_cast<Object*>(java_object)) {
        if (soa.Env()->locals.ContainsDirectPointer(reinterpret_cast<Object*>(java_object))) {
          return JNILocalRefType;
        }
      }

      return JNIInvalidRefType;
    }
    LOG(FATAL) << "IndirectRefKind[" << kind << "]";
    return JNIInvalidRefType;
  }

 private:
  static jint EnsureLocalCapacity(const ScopedObjectAccess& soa, jint desired_capacity,
                                  const char* caller)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    // TODO: we should try to expand the table if necessary.
    if (desired_capacity < 1 || desired_capacity > static_cast<jint>(kLocalsMax)) {
      LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
      return JNI_ERR;
    }
    // TODO: this isn't quite right, since "capacity" includes holes.
    size_t capacity = soa.Env()->locals.Capacity();
    bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
    if (!okay) {
      soa.Self()->ThrowOutOfMemoryError(caller);
    }
    return okay ? JNI_OK : JNI_ERR;
  }

  template<typename JniT, typename ArtT>
  static JniT NewPrimitiveArray(const ScopedObjectAccess& soa, jsize length)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    CHECK_GE(length, 0); // TODO: ReportJniError
    ArtT* result = ArtT::Alloc(length);
    return soa.AddLocalReference<JniT>(result);
  }

  template <typename ArrayT, typename CArrayT, typename ArtArrayT>
  static CArrayT GetPrimitiveArray(ScopedObjectAccess& soa, ArrayT java_array,
                                   jboolean* is_copy)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
    PinPrimitiveArray(soa, array);
    if (is_copy != NULL) {
      *is_copy = JNI_FALSE;
    }
    return array->GetData();
  }

  template <typename ArrayT>
  static void ReleasePrimitiveArray(ScopedObjectAccess& soa, ArrayT java_array,
                                    jint mode)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    if (mode != JNI_COMMIT) {
      Array* array = soa.Decode<Array*>(java_array);
      UnpinPrimitiveArray(soa, array);
    }
  }

  template <typename JavaArrayT, typename JavaT, typename ArrayT>
  static void GetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
                                      jsize start, jsize length, JavaT* buf)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    ArrayT* array = soa.Decode<ArrayT*>(java_array);
    if (start < 0 || length < 0 || start + length > array->GetLength()) {
      ThrowAIOOBE(soa, array, start, length, "src");
    } else {
      JavaT* data = array->GetData();
      memcpy(buf, data + start, length * sizeof(JavaT));
    }
  }

  template <typename JavaArrayT, typename JavaT, typename ArrayT>
  static void SetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
                                      jsize start, jsize length, const JavaT* buf)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    ArrayT* array = soa.Decode<ArrayT*>(java_array);
    if (start < 0 || length < 0 || start + length > array->GetLength()) {
      ThrowAIOOBE(soa, array, start, length, "dst");
    } else {
      JavaT* data = array->GetData();
      memcpy(data + start, buf, length * sizeof(JavaT));
    }
  }
};

const JNINativeInterface gJniNativeInterface = {
  NULL,  // reserved0.
  NULL,  // reserved1.
  NULL,  // reserved2.
  NULL,  // reserved3.
  JNI::GetVersion,
  JNI::DefineClass,
  JNI::FindClass,
  JNI::FromReflectedMethod,
  JNI::FromReflectedField,
  JNI::ToReflectedMethod,
  JNI::GetSuperclass,
  JNI::IsAssignableFrom,
  JNI::ToReflectedField,
  JNI::Throw,
  JNI::ThrowNew,
  JNI::ExceptionOccurred,
  JNI::ExceptionDescribe,
  JNI::ExceptionClear,
  JNI::FatalError,
  JNI::PushLocalFrame,
  JNI::PopLocalFrame,
  JNI::NewGlobalRef,
  JNI::DeleteGlobalRef,
  JNI::DeleteLocalRef,
  JNI::IsSameObject,
  JNI::NewLocalRef,
  JNI::EnsureLocalCapacity,
  JNI::AllocObject,
  JNI::NewObject,
  JNI::NewObjectV,
  JNI::NewObjectA,
  JNI::GetObjectClass,
  JNI::IsInstanceOf,
  JNI::GetMethodID,
  JNI::CallObjectMethod,
  JNI::CallObjectMethodV,
  JNI::CallObjectMethodA,
  JNI::CallBooleanMethod,
  JNI::CallBooleanMethodV,
  JNI::CallBooleanMethodA,
  JNI::CallByteMethod,
  JNI::CallByteMethodV,
  JNI::CallByteMethodA,
  JNI::CallCharMethod,
  JNI::CallCharMethodV,
  JNI::CallCharMethodA,
  JNI::CallShortMethod,
  JNI::CallShortMethodV,
  JNI::CallShortMethodA,
  JNI::CallIntMethod,
  JNI::CallIntMethodV,
  JNI::CallIntMethodA,
  JNI::CallLongMethod,
  JNI::CallLongMethodV,
  JNI::CallLongMethodA,
  JNI::CallFloatMethod,
  JNI::CallFloatMethodV,
  JNI::CallFloatMethodA,
  JNI::CallDoubleMethod,
  JNI::CallDoubleMethodV,
  JNI::CallDoubleMethodA,
  JNI::CallVoidMethod,
  JNI::CallVoidMethodV,
  JNI::CallVoidMethodA,
  JNI::CallNonvirtualObjectMethod,
  JNI::CallNonvirtualObjectMethodV,
  JNI::CallNonvirtualObjectMethodA,
  JNI::CallNonvirtualBooleanMethod,
  JNI::CallNonvirtualBooleanMethodV,
  JNI::CallNonvirtualBooleanMethodA,
  JNI::CallNonvirtualByteMethod,
  JNI::CallNonvirtualByteMethodV,
  JNI::CallNonvirtualByteMethodA,
  JNI::CallNonvirtualCharMethod,
  JNI::CallNonvirtualCharMethodV,
  JNI::CallNonvirtualCharMethodA,
  JNI::CallNonvirtualShortMethod,
  JNI::CallNonvirtualShortMethodV,
  JNI::CallNonvirtualShortMethodA,
  JNI::CallNonvirtualIntMethod,
  JNI::CallNonvirtualIntMethodV,
  JNI::CallNonvirtualIntMethodA,
  JNI::CallNonvirtualLongMethod,
  JNI::CallNonvirtualLongMethodV,
  JNI::CallNonvirtualLongMethodA,
  JNI::CallNonvirtualFloatMethod,
  JNI::CallNonvirtualFloatMethodV,
  JNI::CallNonvirtualFloatMethodA,
  JNI::CallNonvirtualDoubleMethod,
  JNI::CallNonvirtualDoubleMethodV,
  JNI::CallNonvirtualDoubleMethodA,
  JNI::CallNonvirtualVoidMethod,
  JNI::CallNonvirtualVoidMethodV,
  JNI::CallNonvirtualVoidMethodA,
  JNI::GetFieldID,
  JNI::GetObjectField,
  JNI::GetBooleanField,
  JNI::GetByteField,
  JNI::GetCharField,
  JNI::GetShortField,
  JNI::GetIntField,
  JNI::GetLongField,
  JNI::GetFloatField,
  JNI::GetDoubleField,
  JNI::SetObjectField,
  JNI::SetBooleanField,
  JNI::SetByteField,
  JNI::SetCharField,
  JNI::SetShortField,
  JNI::SetIntField,
  JNI::SetLongField,
  JNI::SetFloatField,
  JNI::SetDoubleField,
  JNI::GetStaticMethodID,
  JNI::CallStaticObjectMethod,
  JNI::CallStaticObjectMethodV,
  JNI::CallStaticObjectMethodA,
  JNI::CallStaticBooleanMethod,
  JNI::CallStaticBooleanMethodV,
  JNI::CallStaticBooleanMethodA,
  JNI::CallStaticByteMethod,
  JNI::CallStaticByteMethodV,
  JNI::CallStaticByteMethodA,
  JNI::CallStaticCharMethod,
  JNI::CallStaticCharMethodV,
  JNI::CallStaticCharMethodA,
  JNI::CallStaticShortMethod,
  JNI::CallStaticShortMethodV,
  JNI::CallStaticShortMethodA,
  JNI::CallStaticIntMethod,
  JNI::CallStaticIntMethodV,
  JNI::CallStaticIntMethodA,
  JNI::CallStaticLongMethod,
  JNI::CallStaticLongMethodV,
  JNI::CallStaticLongMethodA,
  JNI::CallStaticFloatMethod,
  JNI::CallStaticFloatMethodV,
  JNI::CallStaticFloatMethodA,
  JNI::CallStaticDoubleMethod,
  JNI::CallStaticDoubleMethodV,
  JNI::CallStaticDoubleMethodA,
  JNI::CallStaticVoidMethod,
  JNI::CallStaticVoidMethodV,
  JNI::CallStaticVoidMethodA,
  JNI::GetStaticFieldID,
  JNI::GetStaticObjectField,
  JNI::GetStaticBooleanField,
  JNI::GetStaticByteField,
  JNI::GetStaticCharField,
  JNI::GetStaticShortField,
  JNI::GetStaticIntField,
  JNI::GetStaticLongField,
  JNI::GetStaticFloatField,
  JNI::GetStaticDoubleField,
  JNI::SetStaticObjectField,
  JNI::SetStaticBooleanField,
  JNI::SetStaticByteField,
  JNI::SetStaticCharField,
  JNI::SetStaticShortField,
  JNI::SetStaticIntField,
  JNI::SetStaticLongField,
  JNI::SetStaticFloatField,
  JNI::SetStaticDoubleField,
  JNI::NewString,
  JNI::GetStringLength,
  JNI::GetStringChars,
  JNI::ReleaseStringChars,
  JNI::NewStringUTF,
  JNI::GetStringUTFLength,
  JNI::GetStringUTFChars,
  JNI::ReleaseStringUTFChars,
  JNI::GetArrayLength,
  JNI::NewObjectArray,
  JNI::GetObjectArrayElement,
  JNI::SetObjectArrayElement,
  JNI::NewBooleanArray,
  JNI::NewByteArray,
  JNI::NewCharArray,
  JNI::NewShortArray,
  JNI::NewIntArray,
  JNI::NewLongArray,
  JNI::NewFloatArray,
  JNI::NewDoubleArray,
  JNI::GetBooleanArrayElements,
  JNI::GetByteArrayElements,
  JNI::GetCharArrayElements,
  JNI::GetShortArrayElements,
  JNI::GetIntArrayElements,
  JNI::GetLongArrayElements,
  JNI::GetFloatArrayElements,
  JNI::GetDoubleArrayElements,
  JNI::ReleaseBooleanArrayElements,
  JNI::ReleaseByteArrayElements,
  JNI::ReleaseCharArrayElements,
  JNI::ReleaseShortArrayElements,
  JNI::ReleaseIntArrayElements,
  JNI::ReleaseLongArrayElements,
  JNI::ReleaseFloatArrayElements,
  JNI::ReleaseDoubleArrayElements,
  JNI::GetBooleanArrayRegion,
  JNI::GetByteArrayRegion,
  JNI::GetCharArrayRegion,
  JNI::GetShortArrayRegion,
  JNI::GetIntArrayRegion,
  JNI::GetLongArrayRegion,
  JNI::GetFloatArrayRegion,
  JNI::GetDoubleArrayRegion,
  JNI::SetBooleanArrayRegion,
  JNI::SetByteArrayRegion,
  JNI::SetCharArrayRegion,
  JNI::SetShortArrayRegion,
  JNI::SetIntArrayRegion,
  JNI::SetLongArrayRegion,
  JNI::SetFloatArrayRegion,
  JNI::SetDoubleArrayRegion,
  JNI::RegisterNatives,
  JNI::UnregisterNatives,
  JNI::MonitorEnter,
  JNI::MonitorExit,
  JNI::GetJavaVM,
  JNI::GetStringRegion,
  JNI::GetStringUTFRegion,
  JNI::GetPrimitiveArrayCritical,
  JNI::ReleasePrimitiveArrayCritical,
  JNI::GetStringCritical,
  JNI::ReleaseStringCritical,
  JNI::NewWeakGlobalRef,
  JNI::DeleteWeakGlobalRef,
  JNI::ExceptionCheck,
  JNI::NewDirectByteBuffer,
  JNI::GetDirectBufferAddress,
  JNI::GetDirectBufferCapacity,
  JNI::GetObjectRefType,
};

JNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm)
    : self(self),
      vm(vm),
      local_ref_cookie(IRT_FIRST_SEGMENT),
      locals(kLocalsInitial, kLocalsMax, kLocal),
      check_jni(false),
      critical(false),
      monitors("monitors", kMonitorsInitial, kMonitorsMax) {
  functions = unchecked_functions = &gJniNativeInterface;
  if (vm->check_jni) {
    SetCheckJniEnabled(true);
  }
  // The JniEnv local reference values must be at a consistent offset or else cross-compilation
  // errors will ensue.
  CHECK_EQ(JNIEnvExt::LocalRefCookieOffset().Int32Value(), 12);
  CHECK_EQ(JNIEnvExt::SegmentStateOffset().Int32Value(), 16);
}

JNIEnvExt::~JNIEnvExt() {
}

void JNIEnvExt::SetCheckJniEnabled(bool enabled) {
  check_jni = enabled;
  functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface;
}

void JNIEnvExt::DumpReferenceTables(std::ostream& os) {
  locals.Dump(os);
  monitors.Dump(os);
}

void JNIEnvExt::PushFrame(int /*capacity*/) {
  // TODO: take 'capacity' into account.
  stacked_local_ref_cookies.push_back(local_ref_cookie);
  local_ref_cookie = locals.GetSegmentState();
}

void JNIEnvExt::PopFrame() {
  locals.SetSegmentState(local_ref_cookie);
  local_ref_cookie = stacked_local_ref_cookies.back();
  stacked_local_ref_cookies.pop_back();
}

// JNI Invocation interface.

extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, void** p_env, void* vm_args) {
  const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
  if (args->version < JNI_VERSION_1_2) {
    return JNI_EVERSION;
  }
  Runtime::Options options;
  for (int i = 0; i < args->nOptions; ++i) {
    JavaVMOption* option = &args->options[i];
    options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
  }
  bool ignore_unrecognized = args->ignoreUnrecognized;
  if (!Runtime::Create(options, ignore_unrecognized)) {
    return JNI_ERR;
  }
  Runtime* runtime = Runtime::Current();
  runtime->Start();
  *p_env = Thread::Current()->GetJniEnv();
  *p_vm = runtime->GetJavaVM();
  return JNI_OK;
}

extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) {
  Runtime* runtime = Runtime::Current();
  if (runtime == NULL) {
    *vm_count = 0;
  } else {
    *vm_count = 1;
    vms[0] = runtime->GetJavaVM();
  }
  return JNI_OK;
}

// Historically unsupported.
extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
  return JNI_ERR;
}

class JII {
 public:
  static jint DestroyJavaVM(JavaVM* vm) {
    if (vm == NULL) {
      return JNI_ERR;
    }
    JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
    delete raw_vm->runtime;
    return JNI_OK;
  }

  static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
    return JII_AttachCurrentThread(vm, p_env, thr_args, false);
  }

  static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
    return JII_AttachCurrentThread(vm, p_env, thr_args, true);
  }

  static jint DetachCurrentThread(JavaVM* vm) {
    if (vm == NULL || Thread::Current() == NULL) {
      return JNI_ERR;
    }
    JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
    Runtime* runtime = raw_vm->runtime;
    runtime->DetachCurrentThread();
    return JNI_OK;
  }

  static jint GetEnv(JavaVM* vm, void** env, jint version) {
    if (version < JNI_VERSION_1_1 || version > JNI_VERSION_1_6) {
      return JNI_EVERSION;
    }
    if (vm == NULL || env == NULL) {
      return JNI_ERR;
    }
    Thread* thread = Thread::Current();
    if (thread == NULL) {
      *env = NULL;
      return JNI_EDETACHED;
    }
    *env = thread->GetJniEnv();
    return JNI_OK;
  }
};

const JNIInvokeInterface gJniInvokeInterface = {
  NULL,  // reserved0
  NULL,  // reserved1
  NULL,  // reserved2
  JII::DestroyJavaVM,
  JII::AttachCurrentThread,
  JII::DetachCurrentThread,
  JII::GetEnv,
  JII::AttachCurrentThreadAsDaemon
};

JavaVMExt::JavaVMExt(Runtime* runtime, Runtime::ParsedOptions* options)
    : runtime(runtime),
      check_jni_abort_hook(NULL),
      check_jni_abort_hook_data(NULL),
      check_jni(false),
      force_copy(false), // TODO: add a way to enable this
      trace(options->jni_trace_),
      work_around_app_jni_bugs(false),
      pins_lock("JNI pin table lock"),
      pin_table("pin table", kPinTableInitial, kPinTableMax),
      globals_lock("JNI global reference table lock"),
      globals(gGlobalsInitial, gGlobalsMax, kGlobal),
      weak_globals_lock("JNI weak global reference table lock"),
      weak_globals(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
      libraries_lock("JNI shared libraries map lock", kLoadLibraryLock),
      libraries(new Libraries) {
  functions = unchecked_functions = &gJniInvokeInterface;
  if (options->check_jni_) {
    SetCheckJniEnabled(true);
  }
}

JavaVMExt::~JavaVMExt() {
  delete libraries;
}

void JavaVMExt::SetCheckJniEnabled(bool enabled) {
  check_jni = enabled;
  functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface;
}

void JavaVMExt::DumpForSigQuit(std::ostream& os) {
  os << "JNI: CheckJNI is " << (check_jni ? "on" : "off");
  if (force_copy) {
    os << " (with forcecopy)";
  }
  os << "; workarounds are " << (work_around_app_jni_bugs ? "on" : "off");
  {
    MutexLock mu(pins_lock);
    os << "; pins=" << pin_table.Size();
  }
  {
    MutexLock mu(globals_lock);
    os << "; globals=" << globals.Capacity();
  }
  {
    MutexLock mu(weak_globals_lock);
    if (weak_globals.Capacity() > 0) {
      os << " (plus " << weak_globals.Capacity() << " weak)";
    }
  }
  os << '\n';

  {
    MutexLock mu(libraries_lock);
    os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
  }
}

void JavaVMExt::DumpReferenceTables(std::ostream& os) {
  {
    MutexLock mu(globals_lock);
    globals.Dump(os);
  }
  {
    MutexLock mu(weak_globals_lock);
    weak_globals.Dump(os);
  }
  {
    MutexLock mu(pins_lock);
    pin_table.Dump(os);
  }
}

bool JavaVMExt::LoadNativeLibrary(const std::string& path, ClassLoader* class_loader,
                                  std::string& detail) {
  detail.clear();

  // See if we've already loaded this library.  If we have, and the class loader
  // matches, return successfully without doing anything.
  // TODO: for better results we should canonicalize the pathname (or even compare
  // inodes). This implementation is fine if everybody is using System.loadLibrary.
  SharedLibrary* library;
  {
    // TODO: move the locking (and more of this logic) into Libraries.
    MutexLock mu(libraries_lock);
    library = libraries->Get(path);
  }
  if (library != NULL) {
    if (library->GetClassLoader() != class_loader) {
      // The library will be associated with class_loader. The JNI
      // spec says we can't load the same library into more than one
      // class loader.
      StringAppendF(&detail, "Shared library \"%s\" already opened by "
          "ClassLoader %p; can't open in ClassLoader %p",
          path.c_str(), library->GetClassLoader(), class_loader);
      LOG(WARNING) << detail;
      return false;
    }
    VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
              << "ClassLoader " << class_loader << "]";
    if (!library->CheckOnLoadResult()) {
      StringAppendF(&detail, "JNI_OnLoad failed on a previous attempt "
          "to load \"%s\"", path.c_str());
      return false;
    }
    return true;
  }

  // Open the shared library.  Because we're using a full path, the system
  // doesn't have to search through LD_LIBRARY_PATH.  (It may do so to
  // resolve this library's dependencies though.)

  // Failures here are expected when java.library.path has several entries
  // and we have to hunt for the lib.

  // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
  // class unloading. Libraries will only be unloaded when the reference count (incremented by
  // dlopen) becomes zero from dlclose.

  // This can execute slowly for a large library on a busy system, so we
  // want to switch from kRunnable while it executes.  This allows the GC to ignore us.
  Thread* self = Thread::Current();
  self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
  void* handle = dlopen(path.empty() ? NULL : path.c_str(), RTLD_LAZY);
  self->TransitionFromSuspendedToRunnable();

  VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]";

  if (handle == NULL) {
    detail = dlerror();
    LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << detail;
    return false;
  }

  // Create a new entry.
  // TODO: move the locking (and more of this logic) into Libraries.
  bool created_library = false;
  {
    MutexLock mu(libraries_lock);
    library = libraries->Get(path);
    if (library == NULL) {  // We won race to get libraries_lock
      library = new SharedLibrary(path, handle, class_loader);
      libraries->Put(path, library);
      created_library = true;
    }
  }
  if (!created_library) {
    LOG(INFO) << "WOW: we lost a race to add shared library: "
        << "\"" << path << "\" ClassLoader=" << class_loader;
    return library->CheckOnLoadResult();
  }

  VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";

  bool result = true;
  void* sym = dlsym(handle, "JNI_OnLoad");
  if (sym == NULL) {
    VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
  } else {
    // Call JNI_OnLoad.  We have to override the current class
    // loader, which will always be "null" since the stuff at the
    // top of the stack is around Runtime.loadLibrary().  (See
    // the comments in the JNI FindClass function.)
    typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
    JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
    ClassLoader* old_class_loader = self->GetClassLoaderOverride();
    self->SetClassLoaderOverride(class_loader);

    int version = 0;
    {
      ScopedThreadStateChange tsc(self, kNative);
      VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
      version = (*jni_on_load)(this, NULL);
    }

    self->SetClassLoaderOverride(old_class_loader);

    if (version != JNI_VERSION_1_2 &&
    version != JNI_VERSION_1_4 &&
    version != JNI_VERSION_1_6) {
      LOG(WARNING) << "JNI_OnLoad in \"" << path << "\" returned "
                   << "bad version: " << version;
      // It's unwise to call dlclose() here, but we can mark it
      // as bad and ensure that future load attempts will fail.
      // We don't know how far JNI_OnLoad got, so there could
      // be some partially-initialized stuff accessible through
      // newly-registered native method calls.  We could try to
      // unregister them, but that doesn't seem worthwhile.
      result = false;
    } else {
      VLOG(jni) << "[Returned " << (result ? "successfully" : "failure")
                << " from JNI_OnLoad in \"" << path << "\"]";
    }
  }

  library->SetResult(result);
  return result;
}

void* JavaVMExt::FindCodeForNativeMethod(AbstractMethod* m) {
  CHECK(m->IsNative());

  Class* c = m->GetDeclaringClass();

  // If this is a static method, it could be called before the class
  // has been initialized.
  if (m->IsStatic()) {
    if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
      return NULL;
    }
  } else {
    CHECK(c->GetStatus() >= Class::kStatusInitializing) << c->GetStatus() << " " << PrettyMethod(m);
  }

  std::string detail;
  void* native_method;
  {
    MutexLock mu(libraries_lock);
    native_method = libraries->FindNativeMethod(m, detail);
  }
  // throwing can cause libraries_lock to be reacquired
  if (native_method == NULL) {
    Thread::Current()->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
  }
  return native_method;
}

void JavaVMExt::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
  {
    MutexLock mu(globals_lock);
    globals.VisitRoots(visitor, arg);
  }
  {
    MutexLock mu(pins_lock);
    pin_table.VisitRoots(visitor, arg);
  }
  // The weak_globals table is visited by the GC itself (because it mutates the table).
}

}  // namespace art

std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
  switch (rhs) {
  case JNIInvalidRefType:
    os << "JNIInvalidRefType";
    return os;
  case JNILocalRefType:
    os << "JNILocalRefType";
    return os;
  case JNIGlobalRefType:
    os << "JNIGlobalRefType";
    return os;
  case JNIWeakGlobalRefType:
    os << "JNIWeakGlobalRefType";
    return os;
  default:
    LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
    return os;
  }
}
