1a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe/*
2a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * Copyright (C) 2015 The Android Open Source Project
3a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe *
4a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License");
5a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * you may not use this file except in compliance with the License.
6a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * You may obtain a copy of the License at
7a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe *
8a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe *      http://www.apache.org/licenses/LICENSE-2.0
9a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe *
10a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * Unless required by applicable law or agreed to in writing, software
11a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS,
12a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * See the License for the specific language governing permissions and
14a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe * limitations under the License.
15a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe */
16a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
17a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "jni.h"
18a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
19a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "base/logging.h"
20a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "dex_file-inl.h"
21a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "mirror/class-inl.h"
22a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "nth_caller_visitor.h"
23a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "runtime.h"
24a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "scoped_thread_state_change.h"
25a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "stack.h"
26a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe#include "thread-inl.h"
27a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
28a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampenamespace art {
29a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
300dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampestatic bool asserts_enabled = true;
31a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
320dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe// public static native void disableStackFrameAsserts();
330dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe// Note: to globally disable asserts in unsupported configurations.
340dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe
350dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampeextern "C" JNIEXPORT void JNICALL Java_Main_disableStackFrameAsserts(JNIEnv* env ATTRIBUTE_UNUSED,
360dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe                                                                     jclass cls ATTRIBUTE_UNUSED) {
370dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe  asserts_enabled = false;
380dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe}
390dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe
400dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe
410dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe// public static native boolean isInterpreted();
420dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe
430dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpreted(JNIEnv* env, jclass) {
44a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  ScopedObjectAccess soa(env);
45a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  NthCallerVisitor caller(soa.Self(), 1, false);
46a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  caller.WalkStack();
47a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  CHECK(caller.caller != nullptr);
4889df7bfc41a4de9685f84e7db07f77db3fd485fcAndreas Gampe  return caller.GetCurrentShadowFrame() != nullptr ? JNI_TRUE : JNI_FALSE;
49a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe}
50a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
510dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe// public static native void assertIsInterpreted();
5289df7bfc41a4de9685f84e7db07f77db3fd485fcAndreas Gampe
530dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampeextern "C" JNIEXPORT void JNICALL Java_Main_assertIsInterpreted(JNIEnv* env, jclass klass) {
540dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe  if (asserts_enabled) {
550dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe    CHECK(Java_Main_isInterpreted(env, klass));
560dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe  }
5789df7bfc41a4de9685f84e7db07f77db3fd485fcAndreas Gampe}
58a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
59a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
600dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe// public static native boolean isManaged();
6189df7bfc41a4de9685f84e7db07f77db3fd485fcAndreas Gampe
620dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_Main_isManaged(JNIEnv* env, jclass cls) {
63a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  ScopedObjectAccess soa(env);
64a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
65a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  mirror::Class* klass = soa.Decode<mirror::Class*>(cls);
66a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  const DexFile& dex_file = klass->GetDexFile();
67a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
68a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  if (oat_dex_file == nullptr) {
69a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe    // No oat file, this must be a test configuration that doesn't compile at all. Ignore that the
70a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe    // result will be that we're running the interpreter.
7189df7bfc41a4de9685f84e7db07f77db3fd485fcAndreas Gampe    return JNI_FALSE;
72a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  }
73a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
74a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  NthCallerVisitor caller(soa.Self(), 1, false);
75a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  caller.WalkStack();
76a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe  CHECK(caller.caller != nullptr);
77a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
7889df7bfc41a4de9685f84e7db07f77db3fd485fcAndreas Gampe  return caller.GetCurrentShadowFrame() != nullptr ? JNI_FALSE : JNI_TRUE;
7989df7bfc41a4de9685f84e7db07f77db3fd485fcAndreas Gampe}
80a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
810dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe// public static native void assertIsManaged();
8289df7bfc41a4de9685f84e7db07f77db3fd485fcAndreas Gampe
830dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampeextern "C" JNIEXPORT void JNICALL Java_Main_assertIsManaged(JNIEnv* env, jclass cls) {
840dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe  if (asserts_enabled) {
850dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe    CHECK(Java_Main_isManaged(env, cls));
860dfc9bc0cca3ae15dc75bbea3ca9b6d7508ce893Andreas Gampe  }
87a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe}
88a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe
89a727e372d8f6929cd30b983f6969c7a50fc83bb6Andreas Gampe}  // namespace art
90