Merge "Revert "Revert "ART: Extracts an utility function of the duplicated code"""
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 4b655b5..8357b8e 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -17,6 +17,7 @@
LOCAL_PATH := art
RUNTIME_GTEST_COMMON_SRC_FILES := \
+ runtime/arch/stub_test.cc \
runtime/barrier_test.cc \
runtime/base/bit_field_test.cc \
runtime/base/bit_vector_test.cc \
diff --git a/runtime/Android.mk b/runtime/Android.mk
index d433fd5..bc971a9 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -36,10 +36,10 @@
base/unix_file/string_file.cc \
check_jni.cc \
catch_block_stack_visitor.cc \
- catch_finder.cc \
class_linker.cc \
common_throws.cc \
debugger.cc \
+ deoptimize_stack_visitor.cc \
dex_file.cc \
dex_file_verifier.cc \
dex_instruction.cc \
@@ -129,6 +129,7 @@
os_linux.cc \
parsed_options.cc \
primitive.cc \
+ quick_exception_handler.cc \
quick/inline_method_analyser.cc \
reference_table.cc \
reflection.cc \
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 4903732..7cc8da8 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -492,11 +492,22 @@
blx lr
.Lcheck_assignability:
push {r0-r2, lr} @ save arguments
+ .save {r0-r2, lr}
+ .cfi_adjust_cfa_offset 16
+ .cfi_rel_offset r0, 0
+ .cfi_rel_offset r1, 4
+ .cfi_rel_offset r2, 8
+ .cfi_rel_offset lr, 12
mov r1, ip
mov r0, r3
bl artIsAssignableFromCode
cbz r0, .Lthrow_array_store_exception
pop {r0-r2, lr}
+ .cfi_restore r0
+ .cfi_restore r1
+ .cfi_restore r2
+ .cfi_restore lr
+ .cfi_adjust_cfa_offset -16
add r3, r0, #OBJECT_ARRAY_DATA_OFFSET
str r2, [r3, r1, lsl #2]
ldr r3, [r9, #THREAD_CARD_TABLE_OFFSET]
@@ -505,6 +516,11 @@
blx lr
.Lthrow_array_store_exception:
pop {r0-r2, lr}
+ .cfi_restore r0
+ .cfi_restore r1
+ .cfi_restore r2
+ .cfi_restore lr
+ .cfi_adjust_cfa_offset -16
SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
mov r1, r2
mov r2, r9 @ pass Thread::Current
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 6ce5d06..1350198 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -864,7 +864,58 @@
UNIMPLEMENTED art_quick_lock_object
UNIMPLEMENTED art_quick_unlock_object
-UNIMPLEMENTED art_quick_check_cast
+
+ /*
+ * Entry from managed code that calls artIsAssignableFromCode and on failure calls
+ * artThrowClassCastException.
+ */
+ .extern artThrowClassCastException
+ENTRY art_quick_check_cast
+ // Store arguments and link register
+ sub sp, sp, #32 // Stack needs to be 16b aligned on calls
+ .cfi_adjust_cfa_offset 32
+ stp x0, x1, [sp]
+ .cfi_rel_offset x0, 0
+ .cfi_rel_offset x1, 8
+ stp xSELF, xLR, [sp, #16]
+ .cfi_rel_offset x18, 16
+ .cfi_rel_offset x30, 24
+
+ // Call runtime code
+ bl artIsAssignableFromCode
+
+ // Check for exception
+ cbz x0, .Lthrow_class_cast_exception
+
+ // Restore and return
+ ldp x0, x1, [sp]
+ .cfi_restore x0
+ .cfi_restore x1
+ ldp xSELF, xLR, [sp, #16]
+ .cfi_restore x18
+ .cfi_restore x30
+ add sp, sp, #32
+ .cfi_adjust_cfa_offset -32
+ ret
+
+.Lthrow_class_cast_exception:
+ // Restore
+ ldp x0, x1, [sp]
+ .cfi_restore x0
+ .cfi_restore x1
+ ldp xSELF, xLR, [sp, #16]
+ .cfi_restore x18
+ .cfi_restore x30
+ add sp, sp, #32
+ .cfi_adjust_cfa_offset -32
+
+ SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
+ mov x2, xSELF // pass Thread::Current
+ mov x3, sp // pass SP
+ b artThrowClassCastException // (Class*, Class*, Thread*, SP)
+ brk 0 // We should not return here...
+END art_quick_check_cast
+
UNIMPLEMENTED art_quick_aput_obj_with_null_and_bound_check
UNIMPLEMENTED art_quick_aput_obj_with_bound_check
UNIMPLEMENTED art_quick_aput_obj
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
new file mode 100644
index 0000000..543e695
--- /dev/null
+++ b/runtime/arch/stub_test.cc
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 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 "common_runtime_test.h"
+
+#include <cstdio>
+
+namespace art {
+
+
+class StubTest : public CommonRuntimeTest {
+ protected:
+ // We need callee-save methods set up in the Runtime for exceptions.
+ void SetUp() OVERRIDE {
+ // Do the normal setup.
+ CommonRuntimeTest::SetUp();
+
+ {
+ // Create callee-save methods
+ ScopedObjectAccess soa(Thread::Current());
+ for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
+ Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
+ if (!runtime_->HasCalleeSaveMethod(type)) {
+ runtime_->SetCalleeSaveMethod(runtime_->CreateCalleeSaveMethod(kRuntimeISA, type), type);
+ }
+ }
+ }
+ }
+
+
+ size_t Invoke3(size_t arg0, size_t arg1, size_t arg2, uintptr_t code, Thread* self) {
+ // Push a transition back into managed code onto the linked list in thread.
+ ManagedStack fragment;
+ self->PushManagedStackFragment(&fragment);
+
+ size_t result;
+#if defined(__i386__)
+ // TODO: Set the thread?
+ __asm__ __volatile__(
+ "pushl $0\n\t" // Push nullptr to terminate quick stack
+ "call *%%edi\n\t" // Call the stub
+ "addl $4, %%esp" // Pop nullptr
+ : "=a" (result)
+ // Use the result from eax
+ : "a"(arg0), "c"(arg1), "d"(arg2), "D"(code)
+ // This places code into edi, arg0 into eax, arg1 into ecx, and arg2 into edx
+ : ); // clobber.
+ // TODO: Should we clobber the other registers? EBX gets clobbered by some of the stubs,
+ // but compilation fails when declaring that.
+#elif defined(__arm__)
+ __asm__ __volatile__(
+ "push {r1-r2,r9, lr}\n\t" // Save the link and thread register
+ ".cfi_adjust_cfa_offset 16\n\t"
+ "mov r0, %[arg0]\n\t" // Set arg0-arg2
+ "mov r1, %[arg1]\n\t" // TODO: Any way to use constraints like on x86?
+ "mov r2, %[arg2]\n\t"
+ // Use r9 last as we don't know whether it was used for arg0-arg2
+ "mov r9, #0\n\t" // Push nullptr to terminate stack
+ "push {r9}\n\t"
+ ".cfi_adjust_cfa_offset 4\n\t"
+ "mov r9, %[self]\n\t" // Set the thread
+ "blx %[code]\n\t" // Call the stub
+ "pop {r1}\n\t" // Pop nullptr
+ ".cfi_adjust_cfa_offset -4\n\t"
+ "pop {r1-r2,r9, lr}\n\t" // Restore the link and thread register
+ ".cfi_adjust_cfa_offset -16\n\t"
+ "mov %[result], r0\n\t" // Save the result
+ : [result] "=r" (result)
+ // Use the result from r0
+ : [arg0] "0"(arg0), [arg1] "r"(arg1), [arg2] "r"(arg2), [code] "r"(code), [self] "r"(self)
+ : ); // clobber.
+#elif defined(__aarch64__)
+ __asm__ __volatile__(
+ "sub sp, sp, #48\n\t" // Reserve stack space, 16B aligned
+ "stp xzr, x1, [sp]\n\t" // nullptr(end of quick stack), x1
+ "stp x2, x18, [sp, #16]\n\t" // Save x2, x18(xSELF)
+ "str x30, [sp, #32]\n\t" // Save xLR
+ "mov x0, %[arg0]\n\t" // Set arg0-arg2
+ "mov x1, %[arg1]\n\t" // TODO: Any way to use constraints like on x86?
+ "mov x2, %[arg2]\n\t"
+ // Use r18 last as we don't know whether it was used for arg0-arg2
+ "mov x18, %[self]\n\t" // Set the thread
+ "blr %[code]\n\t" // Call the stub
+ "ldp x1, x2, [sp, #8]\n\t" // Restore x1, x2
+ "ldp x18, x30, [sp, #24]\n\t" // Restore xSELF, xLR
+ "add sp, sp, #48\n\t" // Free stack space
+ "mov %[result], x0\n\t" // Save the result
+ : [result] "=r" (result)
+ // Use the result from r0
+ : [arg0] "0"(arg0), [arg1] "r"(arg1), [arg2] "r"(arg2), [code] "r"(code), [self] "r"(self)
+ : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17"); // clobber.
+#elif defined(__x86_64__)
+ // Note: Uses the native convention
+ // TODO: Set the thread?
+ __asm__ __volatile__(
+ "pushq $0\n\t" // Push nullptr to terminate quick stack
+ "pushq $0\n\t" // 16B alignment padding
+ "call *%%rax\n\t" // Call the stub
+ "addq $16, %%rsp" // Pop nullptr and padding
+ : "=a" (result)
+ // Use the result from rax
+ : "D"(arg0), "S"(arg1), "d"(arg2), "a"(code)
+ // This places arg0 into rdi, arg1 into rsi, arg2 into rdx, and code into rax
+ : "rcx", "rbp", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"); // clobber all
+ // TODO: Should we clobber the other registers?
+ result = 0;
+#else
+ LOG(WARNING) << "Was asked to invoke for an architecture I do not understand.";
+ result = 0;
+#endif
+ // Pop transition.
+ self->PopManagedStackFragment(fragment);
+ return result;
+ }
+};
+
+
+#if defined(__i386__) || defined(__x86_64__)
+extern "C" void art_quick_memcpy(void);
+#endif
+
+TEST_F(StubTest, Memcpy) {
+#if defined(__i386__) || defined(__x86_64__)
+ Thread* self = Thread::Current();
+
+ uint32_t orig[20];
+ uint32_t trg[20];
+ for (size_t i = 0; i < 20; ++i) {
+ orig[i] = i;
+ trg[i] = 0;
+ }
+
+ Invoke3(reinterpret_cast<size_t>(&trg[4]), reinterpret_cast<size_t>(&orig[4]),
+ 10 * sizeof(uint32_t), reinterpret_cast<uintptr_t>(&art_quick_memcpy), self);
+
+ EXPECT_EQ(orig[0], trg[0]);
+
+ for (size_t i = 1; i < 4; ++i) {
+ EXPECT_NE(orig[i], trg[i]);
+ }
+
+ for (size_t i = 4; i < 14; ++i) {
+ EXPECT_EQ(orig[i], trg[i]);
+ }
+
+ for (size_t i = 14; i < 20; ++i) {
+ EXPECT_NE(orig[i], trg[i]);
+ }
+
+ // TODO: Test overlapping?
+
+#else
+ LOG(INFO) << "Skipping memcpy as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping memcpy as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+
+
+#if defined(__i386__) || defined(__arm__)
+extern "C" void art_quick_lock_object(void);
+#endif
+
+TEST_F(StubTest, LockObject) {
+#if defined(__i386__) || defined(__arm__)
+ Thread* self = Thread::Current();
+ // Create an object
+ ScopedObjectAccess soa(self);
+ // garbage is created during ClassLinker::Init
+
+ SirtRef<mirror::String> obj(soa.Self(),
+ mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!"));
+ LockWord lock = obj->GetLockWord(false);
+ LockWord::LockState old_state = lock.GetState();
+ EXPECT_EQ(LockWord::LockState::kUnlocked, old_state);
+
+ Invoke3(reinterpret_cast<size_t>(obj.get()), 0U, 0U,
+ reinterpret_cast<uintptr_t>(&art_quick_lock_object), self);
+
+ LockWord lock_after = obj->GetLockWord(false);
+ LockWord::LockState new_state = lock_after.GetState();
+ EXPECT_EQ(LockWord::LockState::kThinLocked, new_state);
+
+ Invoke3(reinterpret_cast<size_t>(obj.get()), 0U, 0U,
+ reinterpret_cast<uintptr_t>(&art_quick_lock_object), self);
+
+ LockWord lock_after2 = obj->GetLockWord(false);
+ LockWord::LockState new_state2 = lock_after2.GetState();
+ EXPECT_EQ(LockWord::LockState::kThinLocked, new_state2);
+
+ // TODO: Improve this test. Somehow force it to go to fat locked. But that needs another thread.
+
+#else
+ LOG(INFO) << "Skipping lock_object as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping lock_object as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+
+
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
+extern "C" void art_quick_check_cast(void);
+#endif
+
+TEST_F(StubTest, CheckCast) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
+ Thread* self = Thread::Current();
+ // Find some classes.
+ ScopedObjectAccess soa(self);
+ // garbage is created during ClassLinker::Init
+
+ SirtRef<mirror::Class> c(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
+ "[Ljava/lang/Object;"));
+ SirtRef<mirror::Class> c2(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
+ "[Ljava/lang/String;"));
+
+ EXPECT_FALSE(self->IsExceptionPending());
+
+ Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(c.get()), 0U,
+ reinterpret_cast<uintptr_t>(&art_quick_check_cast), self);
+
+ EXPECT_FALSE(self->IsExceptionPending());
+
+ Invoke3(reinterpret_cast<size_t>(c2.get()), reinterpret_cast<size_t>(c2.get()), 0U,
+ reinterpret_cast<uintptr_t>(&art_quick_check_cast), self);
+
+ EXPECT_FALSE(self->IsExceptionPending());
+
+ Invoke3(reinterpret_cast<size_t>(c.get()), reinterpret_cast<size_t>(c2.get()), 0U,
+ reinterpret_cast<uintptr_t>(&art_quick_check_cast), self);
+
+ EXPECT_FALSE(self->IsExceptionPending());
+
+ // TODO: Make the following work. But that would require correct managed frames.
+
+ Invoke3(reinterpret_cast<size_t>(c2.get()), reinterpret_cast<size_t>(c.get()), 0U,
+ reinterpret_cast<uintptr_t>(&art_quick_check_cast), self);
+
+ EXPECT_TRUE(self->IsExceptionPending());
+ self->ClearException();
+
+#else
+ LOG(INFO) << "Skipping check_cast as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping check_cast as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+
+
+#if defined(__i386__) || defined(__arm__)
+extern "C" void art_quick_aput_obj_with_null_and_bound_check(void);
+// Do not check non-checked ones, we'd need handlers and stuff...
+#endif
+
+TEST_F(StubTest, APutObj) {
+#if defined(__i386__) || defined(__arm__)
+ Thread* self = Thread::Current();
+ // Create an object
+ ScopedObjectAccess soa(self);
+ // garbage is created during ClassLinker::Init
+
+ SirtRef<mirror::Class> c(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/Object;"));
+ SirtRef<mirror::Class> c2(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
+ "Ljava/lang/String;"));
+ SirtRef<mirror::Class> ca(soa.Self(), class_linker_->FindSystemClass(soa.Self(),
+ "[Ljava/lang/String;"));
+
+ // Build a string array of size 1
+ SirtRef<mirror::ObjectArray<mirror::Object> > array(soa.Self(),
+ mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), ca.get(), 1));
+
+ // Build a string -> should be assignable
+ SirtRef<mirror::Object> str_obj(soa.Self(),
+ mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!"));
+
+ // Build a generic object -> should fail assigning
+ SirtRef<mirror::Object> obj_obj(soa.Self(), c->AllocObject(soa.Self()));
+
+ // Play with it...
+
+ // 1) Success cases
+ // 1.1) Assign str_obj to array[0]
+
+ EXPECT_FALSE(self->IsExceptionPending());
+
+ Invoke3(reinterpret_cast<size_t>(array.get()), 0U, reinterpret_cast<size_t>(str_obj.get()),
+ reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
+
+ EXPECT_FALSE(self->IsExceptionPending());
+
+ // 1.2) Assign null to array[0]
+
+ Invoke3(reinterpret_cast<size_t>(array.get()), 0U, reinterpret_cast<size_t>(nullptr),
+ reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
+
+ EXPECT_FALSE(self->IsExceptionPending());
+
+ // TODO: Check _which_ exception is thrown. Then make 3) check that it's the right check order.
+
+ // 2) Failure cases (str into str[])
+ // 2.1) Array = null
+ // TODO: Throwing NPE needs actual DEX code
+
+// Invoke3(reinterpret_cast<size_t>(nullptr), 0U, reinterpret_cast<size_t>(str_obj.get()),
+// reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
+//
+// EXPECT_TRUE(self->IsExceptionPending());
+// self->ClearException();
+
+ // 2.2) Index < 0
+
+ Invoke3(reinterpret_cast<size_t>(array.get()), static_cast<size_t>(-1),
+ reinterpret_cast<size_t>(str_obj.get()),
+ reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
+
+ EXPECT_TRUE(self->IsExceptionPending());
+ self->ClearException();
+
+ // 2.3) Index > 0
+
+ Invoke3(reinterpret_cast<size_t>(array.get()), 1U, reinterpret_cast<size_t>(str_obj.get()),
+ reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
+
+ EXPECT_TRUE(self->IsExceptionPending());
+ self->ClearException();
+
+ // 3) Failure cases (obj into str[])
+
+ Invoke3(reinterpret_cast<size_t>(array.get()), 0U, reinterpret_cast<size_t>(obj_obj.get()),
+ reinterpret_cast<uintptr_t>(&art_quick_aput_obj_with_null_and_bound_check), self);
+
+ EXPECT_TRUE(self->IsExceptionPending());
+ self->ClearException();
+
+ // Tests done.
+#else
+ LOG(INFO) << "Skipping aput_obj as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping aput_obj as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+
+} // namespace art
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 6509a9b..4951ad0 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -666,8 +666,22 @@
END_FUNCTION art_quick_is_assignable
DEFINE_FUNCTION art_quick_check_cast
- int3
- int3
+ PUSH rdi // Save args for exc
+ PUSH rsi
+ call PLT_SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
+ testq %rax, %rax
+ jz 1f // jump forward if not assignable
+ addq LITERAL(16), %rsp // pop arguments
+ CFI_ADJUST_CFA_OFFSET(-16)
+ ret
+1:
+ POP rsi // Pop arguments
+ POP rdi
+ SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
+ mov %rsp, %rcx // pass SP
+ mov %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current()
+ call PLT_SYMBOL(artThrowClassCastException) // (Class* a, Class* b, Thread*, SP)
+ int3 // unreached
END_FUNCTION art_quick_check_cast
/*
@@ -678,7 +692,12 @@
UNIMPLEMENTED art_quick_aput_obj_with_null_and_bound_check
UNIMPLEMENTED art_quick_aput_obj_with_bound_check
UNIMPLEMENTED art_quick_aput_obj
-UNIMPLEMENTED art_quick_memcpy
+
+// TODO: This is quite silly on X86_64 now.
+DEFINE_FUNCTION art_quick_memcpy
+ call PLT_SYMBOL(memcpy) // (void*, const void*, size_t)
+ ret
+END_FUNCTION art_quick_memcpy
NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret
diff --git a/runtime/catch_block_stack_visitor.cc b/runtime/catch_block_stack_visitor.cc
index 410fff9..8d10a97 100644
--- a/runtime/catch_block_stack_visitor.cc
+++ b/runtime/catch_block_stack_visitor.cc
@@ -17,27 +17,26 @@
#include "catch_block_stack_visitor.h"
#include "dex_instruction.h"
-#include "catch_finder.h"
+#include "mirror/art_method-inl.h"
+#include "quick_exception_handler.h"
#include "sirt_ref.h"
#include "verifier/method_verifier.h"
namespace art {
bool CatchBlockStackVisitor::VisitFrame() {
- catch_finder_->SetHandlerFrameId(GetFrameId());
+ exception_handler_->SetHandlerFrameId(GetFrameId());
mirror::ArtMethod* method = GetMethod();
if (method == nullptr) {
// This is the upcall, we remember the frame and last pc so that we may long jump to them.
- catch_finder_->SetHandlerQuickFramePc(GetCurrentQuickFramePc());
- catch_finder_->SetHandlerQuickFrame(GetCurrentQuickFrame());
+ exception_handler_->SetHandlerQuickFramePc(GetCurrentQuickFramePc());
+ exception_handler_->SetHandlerQuickFrame(GetCurrentQuickFrame());
return false; // End stack walk.
} else {
if (method->IsRuntimeMethod()) {
// Ignore callee save method.
DCHECK(method->IsCalleeSaveMethod());
return true;
- } else if (is_deoptimization_) {
- return HandleDeoptimization(method);
} else {
return HandleTryItems(method);
}
@@ -46,68 +45,21 @@
bool CatchBlockStackVisitor::HandleTryItems(mirror::ArtMethod* method) {
uint32_t dex_pc = DexFile::kDexNoIndex;
- if (method->IsNative()) {
- ++native_method_count_;
- } else {
+ if (!method->IsNative()) {
dex_pc = GetDexPc();
}
if (dex_pc != DexFile::kDexNoIndex) {
bool clear_exception = false;
- SirtRef<mirror::Class> sirt_method_to_find(Thread::Current(), to_find_);
- uint32_t found_dex_pc = method->FindCatchBlock(sirt_method_to_find, dex_pc, &clear_exception);
- to_find_ = sirt_method_to_find.get();
- catch_finder_->SetClearException(clear_exception);
+ uint32_t found_dex_pc = method->FindCatchBlock(to_find_, dex_pc, &clear_exception);
+ exception_handler_->SetClearException(clear_exception);
if (found_dex_pc != DexFile::kDexNoIndex) {
- catch_finder_->SetHandlerDexPc(found_dex_pc);
- catch_finder_->SetHandlerQuickFramePc(method->ToNativePc(found_dex_pc));
- catch_finder_->SetHandlerQuickFrame(GetCurrentQuickFrame());
+ exception_handler_->SetHandlerDexPc(found_dex_pc);
+ exception_handler_->SetHandlerQuickFramePc(method->ToNativePc(found_dex_pc));
+ exception_handler_->SetHandlerQuickFrame(GetCurrentQuickFrame());
return false; // End stack walk.
}
}
return true; // Continue stack walk.
}
-bool CatchBlockStackVisitor::HandleDeoptimization(mirror::ArtMethod* m) {
- MethodHelper mh(m);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
- CHECK(code_item != nullptr);
- uint16_t num_regs = code_item->registers_size_;
- uint32_t dex_pc = GetDexPc();
- const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
- uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
- ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, m, new_dex_pc);
- SirtRef<mirror::DexCache> dex_cache(self_, mh.GetDexCache());
- SirtRef<mirror::ClassLoader> class_loader(self_, mh.GetClassLoader());
- verifier::MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader,
- &mh.GetClassDef(), code_item, m->GetDexMethodIndex(), m,
- m->GetAccessFlags(), false, true);
- verifier.Verify();
- std::vector<int32_t> kinds = verifier.DescribeVRegs(dex_pc);
- for (uint16_t reg = 0; reg < num_regs; ++reg) {
- VRegKind kind = static_cast<VRegKind>(kinds.at(reg * 2));
- switch (kind) {
- case kUndefined:
- new_frame->SetVReg(reg, 0xEBADDE09);
- break;
- case kConstant:
- new_frame->SetVReg(reg, kinds.at((reg * 2) + 1));
- break;
- case kReferenceVReg:
- new_frame->SetVRegReference(reg,
- reinterpret_cast<mirror::Object*>(GetVReg(m, reg, kind)));
- break;
- default:
- new_frame->SetVReg(reg, GetVReg(m, reg, kind));
- break;
- }
- }
- if (prev_shadow_frame_ != nullptr) {
- prev_shadow_frame_->SetLink(new_frame);
- } else {
- catch_finder_->SetTopShadowFrame(new_frame);
- }
- prev_shadow_frame_ = new_frame;
- return true;
-}
-
} // namespace art
diff --git a/runtime/catch_block_stack_visitor.h b/runtime/catch_block_stack_visitor.h
index ce67e27..6f0fe11 100644
--- a/runtime/catch_block_stack_visitor.h
+++ b/runtime/catch_block_stack_visitor.h
@@ -17,39 +17,39 @@
#ifndef ART_RUNTIME_CATCH_BLOCK_STACK_VISITOR_H_
#define ART_RUNTIME_CATCH_BLOCK_STACK_VISITOR_H_
-#include "mirror/throwable.h"
-#include "thread.h"
+#include "mirror/object-inl.h"
+#include "stack.h"
+#include "sirt_ref-inl.h"
namespace art {
-class CatchFinder;
+
+namespace mirror {
+class Throwable;
+} // namespace mirror
+class Context;
+class QuickExceptionHandler;
+class Thread;
class ThrowLocation;
// Finds catch handler or prepares deoptimization.
-class CatchBlockStackVisitor : public StackVisitor {
+class CatchBlockStackVisitor FINAL : public StackVisitor {
public:
- CatchBlockStackVisitor(Thread* self, Context* context, mirror::Throwable* exception,
- bool is_deoptimization, CatchFinder* catch_finder)
+ CatchBlockStackVisitor(Thread* self, Context* context, SirtRef<mirror::Throwable>& exception,
+ QuickExceptionHandler* exception_handler)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : StackVisitor(self, context),
- self_(self), is_deoptimization_(is_deoptimization),
- to_find_(is_deoptimization ? nullptr : exception->GetClass()),
- catch_finder_(catch_finder), native_method_count_(0), prev_shadow_frame_(nullptr) {
+ : StackVisitor(self, context), self_(self), to_find_(self, exception->GetClass()),
+ exception_handler_(exception_handler) {
}
- bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool VisitFrame() OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
private:
bool HandleTryItems(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool HandleDeoptimization(mirror::ArtMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Thread* const self_;
- const bool is_deoptimization_;
// The type of the exception catch block to find.
- mirror::Class* to_find_;
- CatchFinder* const catch_finder_;
- // Number of native methods passed in crawl (equates to number of SIRTs to pop)
- uint32_t native_method_count_;
- ShadowFrame* prev_shadow_frame_;
+ SirtRef<mirror::Class> to_find_;
+ QuickExceptionHandler* const exception_handler_;
DISALLOW_COPY_AND_ASSIGN(CatchBlockStackVisitor);
};
diff --git a/runtime/deoptimize_stack_visitor.cc b/runtime/deoptimize_stack_visitor.cc
new file mode 100644
index 0000000..f2eaf00
--- /dev/null
+++ b/runtime/deoptimize_stack_visitor.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 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 "deoptimize_stack_visitor.h"
+
+#include "mirror/art_method-inl.h"
+#include "object_utils.h"
+#include "quick_exception_handler.h"
+#include "sirt_ref-inl.h"
+#include "verifier/method_verifier.h"
+
+namespace art {
+
+bool DeoptimizeStackVisitor::VisitFrame() {
+ exception_handler_->SetHandlerFrameId(GetFrameId());
+ mirror::ArtMethod* method = GetMethod();
+ if (method == nullptr) {
+ // This is the upcall, we remember the frame and last pc so that we may long jump to them.
+ exception_handler_->SetHandlerQuickFramePc(GetCurrentQuickFramePc());
+ exception_handler_->SetHandlerQuickFrame(GetCurrentQuickFrame());
+ return false; // End stack walk.
+ } else if (method->IsRuntimeMethod()) {
+ // Ignore callee save method.
+ DCHECK(method->IsCalleeSaveMethod());
+ return true;
+ } else {
+ return HandleDeoptimization(method);
+ }
+}
+
+bool DeoptimizeStackVisitor::HandleDeoptimization(mirror::ArtMethod* m) {
+ MethodHelper mh(m);
+ const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ CHECK(code_item != nullptr);
+ uint16_t num_regs = code_item->registers_size_;
+ uint32_t dex_pc = GetDexPc();
+ const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
+ uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
+ ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, m, new_dex_pc);
+ SirtRef<mirror::DexCache> dex_cache(self_, mh.GetDexCache());
+ SirtRef<mirror::ClassLoader> class_loader(self_, mh.GetClassLoader());
+ verifier::MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader,
+ &mh.GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+ m->GetAccessFlags(), false, true);
+ verifier.Verify();
+ std::vector<int32_t> kinds = verifier.DescribeVRegs(dex_pc);
+ for (uint16_t reg = 0; reg < num_regs; ++reg) {
+ VRegKind kind = static_cast<VRegKind>(kinds.at(reg * 2));
+ switch (kind) {
+ case kUndefined:
+ new_frame->SetVReg(reg, 0xEBADDE09);
+ break;
+ case kConstant:
+ new_frame->SetVReg(reg, kinds.at((reg * 2) + 1));
+ break;
+ case kReferenceVReg:
+ new_frame->SetVRegReference(reg,
+ reinterpret_cast<mirror::Object*>(GetVReg(m, reg, kind)));
+ break;
+ default:
+ new_frame->SetVReg(reg, GetVReg(m, reg, kind));
+ break;
+ }
+ }
+ if (prev_shadow_frame_ != nullptr) {
+ prev_shadow_frame_->SetLink(new_frame);
+ } else {
+ exception_handler_->SetTopShadowFrame(new_frame);
+ }
+ prev_shadow_frame_ = new_frame;
+ return true;
+}
+
+} // namespace art
diff --git a/runtime/deoptimize_stack_visitor.h b/runtime/deoptimize_stack_visitor.h
new file mode 100644
index 0000000..c898e7d
--- /dev/null
+++ b/runtime/deoptimize_stack_visitor.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef ART_RUNTIME_DEOPTIMIZE_STACK_VISITOR_H_
+#define ART_RUNTIME_DEOPTIMIZE_STACK_VISITOR_H_
+
+#include "base/mutex.h"
+#include "stack.h"
+
+namespace art {
+
+namespace mirror {
+class ArtMethod;
+} // namespace mirror
+class QuickExceptionHandler;
+class Thread;
+
+// Prepares deoptimization.
+class DeoptimizeStackVisitor FINAL : public StackVisitor {
+ public:
+ DeoptimizeStackVisitor(Thread* self, Context* context, QuickExceptionHandler* exception_handler)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : StackVisitor(self, context), self_(self), exception_handler_(exception_handler),
+ prev_shadow_frame_(nullptr) {
+ }
+
+ bool VisitFrame() OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+ bool HandleDeoptimization(mirror::ArtMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Thread* const self_;
+ QuickExceptionHandler* const exception_handler_;
+ ShadowFrame* prev_shadow_frame_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeoptimizeStackVisitor);
+};
+
+} // namespace art
+#endif // ART_RUNTIME_DEOPTIMIZE_STACK_VISITOR_H_
diff --git a/runtime/entrypoints/quick/quick_deoptimization_entrypoints.cc b/runtime/entrypoints/quick/quick_deoptimization_entrypoints.cc
index 51c647a..6448045 100644
--- a/runtime/entrypoints/quick/quick_deoptimization_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_deoptimization_entrypoints.cc
@@ -31,7 +31,7 @@
extern "C" void artDeoptimize(Thread* self, mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
- self->SetException(ThrowLocation(), reinterpret_cast<mirror::Throwable*>(-1));
+ self->SetException(ThrowLocation(), Thread::GetDeoptimizationException());
self->QuickDeliverException();
}
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 65bdf0e..cc1fa0c 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -169,6 +169,13 @@
return false;
}
}
+ // Report this field access to instrumentation if needed.
+ instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
+ if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
+ Object* this_object = f->IsStatic() ? nullptr : obj;
+ instrumentation->FieldReadEvent(self, this_object, shadow_frame.GetMethod(),
+ shadow_frame.GetDexPC(), f);
+ }
uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
switch (field_type) {
case Primitive::kPrimBoolean:
@@ -210,6 +217,17 @@
return false;
}
MemberOffset field_offset(inst->VRegC_22c());
+ // Report this field access to instrumentation if needed. Since we only have the offset of
+ // the field from the base of the object, we need to look for it first.
+ instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
+ if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
+ ArtField* f = ArtField::FindInstanceFieldWithOffset(obj->GetClass(),
+ field_offset.Uint32Value());
+ DCHECK(f != nullptr);
+ DCHECK(!f->IsStatic());
+ instrumentation->FieldReadEvent(Thread::Current(), obj, shadow_frame.GetMethod(),
+ shadow_frame.GetDexPC(), f);
+ }
const bool is_volatile = false; // iget-x-quick only on non volatile fields.
const uint32_t vregA = inst->VRegA_22c(inst_data);
switch (field_type) {
@@ -228,6 +246,39 @@
return true;
}
+template<Primitive::Type field_type>
+static inline JValue GetFieldValue(const ShadowFrame& shadow_frame, uint32_t vreg)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ JValue field_value;
+ switch (field_type) {
+ case Primitive::kPrimBoolean:
+ field_value.SetZ(static_cast<uint8_t>(shadow_frame.GetVReg(vreg)));
+ break;
+ case Primitive::kPrimByte:
+ field_value.SetB(static_cast<int8_t>(shadow_frame.GetVReg(vreg)));
+ break;
+ case Primitive::kPrimChar:
+ field_value.SetC(static_cast<uint16_t>(shadow_frame.GetVReg(vreg)));
+ break;
+ case Primitive::kPrimShort:
+ field_value.SetS(static_cast<int16_t>(shadow_frame.GetVReg(vreg)));
+ break;
+ case Primitive::kPrimInt:
+ field_value.SetI(shadow_frame.GetVReg(vreg));
+ break;
+ case Primitive::kPrimLong:
+ field_value.SetJ(shadow_frame.GetVRegLong(vreg));
+ break;
+ case Primitive::kPrimNot:
+ field_value.SetL(shadow_frame.GetVRegReference(vreg));
+ break;
+ default:
+ LOG(FATAL) << "Unreachable: " << field_type;
+ break;
+ }
+ return field_value;
+}
+
// Handles iput-XXX and sput-XXX instructions.
// Returns true on success, otherwise throws an exception and returns false.
template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check, bool transaction_active>
@@ -254,6 +305,15 @@
}
}
uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
+ // Report this field access to instrumentation if needed. Since we only have the offset of
+ // the field from the base of the object, we need to look for it first.
+ instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
+ if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
+ JValue field_value = GetFieldValue<field_type>(shadow_frame, vregA);
+ Object* this_object = f->IsStatic() ? nullptr : obj;
+ instrumentation->FieldWriteEvent(self, this_object, shadow_frame.GetMethod(),
+ shadow_frame.GetDexPC(), f, field_value);
+ }
switch (field_type) {
case Primitive::kPrimBoolean:
f->SetBoolean<transaction_active>(obj, shadow_frame.GetVReg(vregA));
@@ -309,8 +369,20 @@
return false;
}
MemberOffset field_offset(inst->VRegC_22c());
- const bool is_volatile = false; // iput-x-quick only on non volatile fields.
const uint32_t vregA = inst->VRegA_22c(inst_data);
+ // Report this field modification to instrumentation if needed. Since we only have the offset of
+ // the field from the base of the object, we need to look for it first.
+ instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
+ if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
+ ArtField* f = ArtField::FindInstanceFieldWithOffset(obj->GetClass(),
+ field_offset.Uint32Value());
+ DCHECK(f != nullptr);
+ DCHECK(!f->IsStatic());
+ JValue field_value = GetFieldValue<field_type>(shadow_frame, vregA);
+ instrumentation->FieldWriteEvent(Thread::Current(), obj, shadow_frame.GetMethod(),
+ shadow_frame.GetDexPC(), f, field_value);
+ }
+ const bool is_volatile = false; // iput-x-quick only on non volatile fields.
switch (field_type) {
case Primitive::kPrimInt:
obj->SetField32<transaction_active>(field_offset, shadow_frame.GetVReg(vregA), is_volatile);
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index adc1074..223b7a1 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -108,7 +108,7 @@
*/
struct ModBasket {
ModBasket() : pLoc(NULL), threadId(0), classId(0), excepClassId(0),
- caught(false), field(0), thisPtr(0) { }
+ caught(false), fieldTypeID(0), fieldId(0), thisPtr(0) { }
const JdwpLocation* pLoc; /* LocationOnly */
std::string className; /* ClassMatch/ClassExclude */
@@ -116,7 +116,8 @@
RefTypeId classId; /* ClassOnly */
RefTypeId excepClassId; /* ExceptionOnly */
bool caught; /* ExceptionOnly */
- FieldId field; /* FieldOnly */
+ RefTypeId fieldTypeID; /* FieldOnly */
+ FieldId fieldId; /* FieldOnly */
ObjectId thisPtr; /* InstanceOnly */
/* nothing for StepOnly -- handled differently */
};
@@ -457,7 +458,10 @@
}
break;
case MK_FIELD_ONLY:
- if (!Dbg::MatchType(basket->classId, pMod->fieldOnly.refTypeId) || pMod->fieldOnly.fieldId != basket->field) {
+ if (pMod->fieldOnly.fieldId != basket->fieldId) {
+ return false;
+ }
+ if (!Dbg::MatchType(basket->fieldTypeID, pMod->fieldOnly.refTypeId)) {
return false;
}
break;
@@ -848,7 +852,8 @@
basket.thisPtr = thisPtr;
basket.threadId = Dbg::GetThreadSelfId();
basket.className = Dbg::GetClassName(pLoc->class_id);
- basket.field = fieldId;
+ basket.fieldTypeID = typeId;
+ basket.fieldId = fieldId;
if (InvokeInProgress()) {
VLOG(jdwp) << "Not posting field event during invoke";
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 8ef375b..4843c2b 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -354,8 +354,8 @@
static JdwpError VM_Capabilities(JdwpState*, Request&, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- expandBufAdd1(reply, false); // canWatchFieldModification
- expandBufAdd1(reply, false); // canWatchFieldAccess
+ expandBufAdd1(reply, true); // canWatchFieldModification
+ expandBufAdd1(reply, true); // canWatchFieldAccess
expandBufAdd1(reply, true); // canGetBytecodes
expandBufAdd1(reply, true); // canGetSyntheticAttribute
expandBufAdd1(reply, true); // canGetOwnedMonitorInfo
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index c04aabf..fd9c40b 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -513,14 +513,16 @@
SafeMap<std::string, SharedLibrary*> libraries_;
};
-#define CHECK_NON_NULL_ARGUMENT(fn, value) \
+#define CHECK_NON_NULL_ARGUMENT(value) CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value)
+
+#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value) \
if (UNLIKELY(value == nullptr)) { \
- JniAbortF(#fn, #value " == null"); \
+ JniAbortF(name, #value " == null"); \
}
-#define CHECK_NON_NULL_MEMCPY_ARGUMENT(fn, length, value) \
+#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
if (UNLIKELY(length != 0 && value == nullptr)) { \
- JniAbortF(#fn, #value " == null"); \
+ JniAbortF(__FUNCTION__, #value " == null"); \
}
class JNI {
@@ -535,7 +537,7 @@
}
static jclass FindClass(JNIEnv* env, const char* name) {
- CHECK_NON_NULL_ARGUMENT(FindClass, name);
+ CHECK_NON_NULL_ARGUMENT(name);
Runtime* runtime = Runtime::Current();
ClassLinker* class_linker = runtime->GetClassLinker();
std::string descriptor(NormalizeJniClassDescriptor(name));
@@ -551,19 +553,19 @@
}
static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
- CHECK_NON_NULL_ARGUMENT(FromReflectedMethod, jlr_method);
+ CHECK_NON_NULL_ARGUMENT(jlr_method);
ScopedObjectAccess soa(env);
return soa.EncodeMethod(mirror::ArtMethod::FromReflectedMethod(soa, jlr_method));
}
static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
- CHECK_NON_NULL_ARGUMENT(FromReflectedField, jlr_field);
+ CHECK_NON_NULL_ARGUMENT(jlr_field);
ScopedObjectAccess soa(env);
return soa.EncodeField(mirror::ArtField::FromReflectedField(soa, jlr_field));
}
static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
- CHECK_NON_NULL_ARGUMENT(ToReflectedMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
mirror::ArtMethod* m = soa.DecodeMethod(mid);
CHECK(!kMovingMethods);
@@ -578,7 +580,7 @@
}
static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
- CHECK_NON_NULL_ARGUMENT(ToReflectedField, fid);
+ CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
mirror::ArtField* f = soa.DecodeField(fid);
jobject art_field = soa.AddLocalReference<jobject>(f);
@@ -592,22 +594,22 @@
}
static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
- CHECK_NON_NULL_ARGUMENT(GetObjectClass, java_object);
+ CHECK_NON_NULL_ARGUMENT(java_object);
ScopedObjectAccess soa(env);
mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
return soa.AddLocalReference<jclass>(o->GetClass());
}
static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
- CHECK_NON_NULL_ARGUMENT(GetSuperclass, java_class);
+ CHECK_NON_NULL_ARGUMENT(java_class);
ScopedObjectAccess soa(env);
mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
return soa.AddLocalReference<jclass>(c->GetSuperClass());
}
static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
- CHECK_NON_NULL_ARGUMENT(IsAssignableFrom, java_class1);
- CHECK_NON_NULL_ARGUMENT(IsAssignableFrom, java_class2);
+ CHECK_NON_NULL_ARGUMENT(java_class1);
+ CHECK_NON_NULL_ARGUMENT(java_class2);
ScopedObjectAccess soa(env);
mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
@@ -615,7 +617,7 @@
}
static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
- CHECK_NON_NULL_ARGUMENT(IsInstanceOf, java_class);
+ CHECK_NON_NULL_ARGUMENT(java_class);
if (jobj == nullptr) {
// Note: JNI is different from regular Java instanceof in this respect
return JNI_TRUE;
@@ -639,7 +641,7 @@
}
static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
- CHECK_NON_NULL_ARGUMENT(ThrowNew, c);
+ CHECK_NON_NULL_ARGUMENT(c);
return ThrowNewException(env, c, msg, nullptr);
}
@@ -797,7 +799,7 @@
}
static jobject AllocObject(JNIEnv* env, jclass java_class) {
- CHECK_NON_NULL_ARGUMENT(AllocObject, java_class);
+ CHECK_NON_NULL_ARGUMENT(java_class);
ScopedObjectAccess soa(env);
mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
if (c == nullptr) {
@@ -809,16 +811,16 @@
static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
va_list args;
va_start(args, mid);
- CHECK_NON_NULL_ARGUMENT(NewObject, java_class);
- CHECK_NON_NULL_ARGUMENT(NewObject, mid);
+ CHECK_NON_NULL_ARGUMENT(java_class);
+ CHECK_NON_NULL_ARGUMENT(mid);
jobject result = NewObjectV(env, java_class, mid, args);
va_end(args);
return result;
}
static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(NewObjectV, java_class);
- CHECK_NON_NULL_ARGUMENT(NewObjectV, mid);
+ CHECK_NON_NULL_ARGUMENT(java_class);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
if (c == nullptr) {
@@ -837,8 +839,8 @@
}
static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(NewObjectA, java_class);
- CHECK_NON_NULL_ARGUMENT(NewObjectA, mid);
+ CHECK_NON_NULL_ARGUMENT(java_class);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
if (c == nullptr) {
@@ -857,18 +859,18 @@
}
static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
- CHECK_NON_NULL_ARGUMENT(GetMethodID, java_class);
- CHECK_NON_NULL_ARGUMENT(GetMethodID, name);
- CHECK_NON_NULL_ARGUMENT(GetMethodID, sig);
+ CHECK_NON_NULL_ARGUMENT(java_class);
+ CHECK_NON_NULL_ARGUMENT(name);
+ CHECK_NON_NULL_ARGUMENT(sig);
ScopedObjectAccess soa(env);
return FindMethodID(soa, java_class, name, sig, false);
}
static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
const char* sig) {
- CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, java_class);
- CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, name);
- CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, sig);
+ CHECK_NON_NULL_ARGUMENT(java_class);
+ CHECK_NON_NULL_ARGUMENT(name);
+ CHECK_NON_NULL_ARGUMENT(sig);
ScopedObjectAccess soa(env);
return FindMethodID(soa, java_class, name, sig, true);
}
@@ -876,8 +878,8 @@
static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallObjectMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallObjectMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -885,16 +887,16 @@
}
static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
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) {
- CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args));
@@ -904,8 +906,8 @@
static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -913,15 +915,15 @@
}
static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
}
static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args).GetZ();
@@ -930,8 +932,8 @@
static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallByteMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallByteMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -939,15 +941,15 @@
}
static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallByteMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallByteMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
}
static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallByteMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallByteMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args).GetB();
@@ -956,8 +958,8 @@
static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallCharMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallCharMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -965,15 +967,15 @@
}
static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallCharMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallCharMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
}
static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallCharMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallCharMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args).GetC();
@@ -982,8 +984,8 @@
static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -991,15 +993,15 @@
}
static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
}
static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args).GetD();
@@ -1008,8 +1010,8 @@
static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallFloatMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallFloatMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1017,15 +1019,15 @@
}
static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
}
static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args).GetF();
@@ -1034,8 +1036,8 @@
static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallIntMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallIntMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1043,15 +1045,15 @@
}
static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallIntMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallIntMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
}
static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallIntMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallIntMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args).GetI();
@@ -1060,8 +1062,8 @@
static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallLongMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallLongMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1069,15 +1071,15 @@
}
static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallLongMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallLongMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
}
static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallLongMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallLongMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args).GetJ();
@@ -1086,8 +1088,8 @@
static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallShortMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallShortMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1095,15 +1097,15 @@
}
static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallShortMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallShortMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
}
static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallShortMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallShortMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
args).GetS();
@@ -1112,23 +1114,23 @@
static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallVoidMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallVoidMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
va_end(ap);
}
static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
}
static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
}
@@ -1136,8 +1138,8 @@
static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
@@ -1147,8 +1149,8 @@
static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, args));
return soa.AddLocalReference<jobject>(result.GetL());
@@ -1156,8 +1158,8 @@
static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args));
return soa.AddLocalReference<jobject>(result.GetL());
@@ -1167,8 +1169,8 @@
...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1177,16 +1179,16 @@
static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
}
static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetZ();
}
@@ -1194,8 +1196,8 @@
static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1204,16 +1206,16 @@
static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, obj, mid, args).GetB();
}
static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetB();
}
@@ -1221,8 +1223,8 @@
static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1231,16 +1233,16 @@
static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, obj, mid, args).GetC();
}
static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetC();
}
@@ -1248,8 +1250,8 @@
static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1258,16 +1260,16 @@
static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, obj, mid, args).GetS();
}
static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetS();
}
@@ -1275,8 +1277,8 @@
static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1285,16 +1287,16 @@
static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, obj, mid, args).GetI();
}
static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetI();
}
@@ -1302,8 +1304,8 @@
static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1312,16 +1314,16 @@
static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
}
static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetJ();
}
@@ -1329,8 +1331,8 @@
static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1339,16 +1341,16 @@
static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, obj, mid, args).GetF();
}
static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetF();
}
@@ -1356,8 +1358,8 @@
static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
va_end(ap);
@@ -1366,16 +1368,16 @@
static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, obj, mid, args).GetD();
}
static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetD();
}
@@ -1383,8 +1385,8 @@
static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeWithVarArgs(soa, obj, mid, ap);
va_end(ap);
@@ -1392,40 +1394,40 @@
static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeWithVarArgs(soa, obj, mid, args);
}
static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, obj);
- CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
}
static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
- CHECK_NON_NULL_ARGUMENT(GetFieldID, java_class);
- CHECK_NON_NULL_ARGUMENT(GetFieldID, name);
- CHECK_NON_NULL_ARGUMENT(GetFieldID, sig);
+ CHECK_NON_NULL_ARGUMENT(java_class);
+ CHECK_NON_NULL_ARGUMENT(name);
+ CHECK_NON_NULL_ARGUMENT(sig);
ScopedObjectAccess soa(env);
return FindFieldID(soa, java_class, name, sig, false);
}
static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
const char* sig) {
- CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, java_class);
- CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, name);
- CHECK_NON_NULL_ARGUMENT(GetFieldID, sig);
+ CHECK_NON_NULL_ARGUMENT(java_class);
+ CHECK_NON_NULL_ARGUMENT(name);
+ CHECK_NON_NULL_ARGUMENT(sig);
ScopedObjectAccess soa(env);
return FindFieldID(soa, java_class, name, sig, true);
}
static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
- CHECK_NON_NULL_ARGUMENT(GetObjectField, obj);
- CHECK_NON_NULL_ARGUMENT(GetObjectField, fid);
+ CHECK_NON_NULL_ARGUMENT(obj);
+ CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
mirror::Object* o = soa.Decode<mirror::Object*>(obj);
mirror::ArtField* f = soa.DecodeField(fid);
@@ -1433,15 +1435,15 @@
}
static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
- CHECK_NON_NULL_ARGUMENT(GetStaticObjectField, fid);
+ CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
mirror::ArtField* f = soa.DecodeField(fid);
return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
}
static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
- CHECK_NON_NULL_ARGUMENT(SetObjectField, java_object);
- CHECK_NON_NULL_ARGUMENT(SetObjectField, fid);
+ CHECK_NON_NULL_ARGUMENT(java_object);
+ CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
@@ -1450,7 +1452,7 @@
}
static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
- CHECK_NON_NULL_ARGUMENT(SetStaticObjectField, fid);
+ CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
mirror::ArtField* f = soa.DecodeField(fid);
@@ -1458,29 +1460,29 @@
}
#define GET_PRIMITIVE_FIELD(fn, instance) \
- CHECK_NON_NULL_ARGUMENT(Get #fn Field, instance); \
- CHECK_NON_NULL_ARGUMENT(Get #fn Field, fid); \
+ CHECK_NON_NULL_ARGUMENT(instance); \
+ CHECK_NON_NULL_ARGUMENT(fid); \
ScopedObjectAccess soa(env); \
mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
mirror::ArtField* f = soa.DecodeField(fid); \
return f->Get ##fn (o)
#define GET_STATIC_PRIMITIVE_FIELD(fn) \
- CHECK_NON_NULL_ARGUMENT(GetStatic #fn Field, fid); \
+ CHECK_NON_NULL_ARGUMENT(fid); \
ScopedObjectAccess soa(env); \
mirror::ArtField* f = soa.DecodeField(fid); \
return f->Get ##fn (f->GetDeclaringClass())
#define SET_PRIMITIVE_FIELD(fn, instance, value) \
- CHECK_NON_NULL_ARGUMENT(Set #fn Field, instance); \
- CHECK_NON_NULL_ARGUMENT(Set #fn Field, fid); \
+ CHECK_NON_NULL_ARGUMENT(instance); \
+ CHECK_NON_NULL_ARGUMENT(fid); \
ScopedObjectAccess soa(env); \
mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
mirror::ArtField* f = soa.DecodeField(fid); \
f->Set ##fn <false>(o, value)
#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
- CHECK_NON_NULL_ARGUMENT(SetStatic #fn Field, fid); \
+ CHECK_NON_NULL_ARGUMENT(fid); \
ScopedObjectAccess soa(env); \
mirror::ArtField* f = soa.DecodeField(fid); \
f->Set ##fn <false>(f->GetDeclaringClass(), value)
@@ -1616,7 +1618,7 @@
static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
@@ -1625,14 +1627,14 @@
}
static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
return soa.AddLocalReference<jobject>(result.GetL());
}
static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithJValues(soa, nullptr, mid, args));
return soa.AddLocalReference<jobject>(result.GetL());
@@ -1641,7 +1643,7 @@
static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
va_end(ap);
@@ -1649,13 +1651,13 @@
}
static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
}
static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
}
@@ -1663,7 +1665,7 @@
static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticByteMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
va_end(ap);
@@ -1671,13 +1673,13 @@
}
static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
}
static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, nullptr, mid, args).GetB();
}
@@ -1685,7 +1687,7 @@
static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticCharMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
va_end(ap);
@@ -1693,13 +1695,13 @@
}
static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
}
static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, nullptr, mid, args).GetC();
}
@@ -1707,7 +1709,7 @@
static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticShortMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
va_end(ap);
@@ -1715,13 +1717,13 @@
}
static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
}
static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, nullptr, mid, args).GetS();
}
@@ -1729,7 +1731,7 @@
static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticIntMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
va_end(ap);
@@ -1737,13 +1739,13 @@
}
static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
}
static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, nullptr, mid, args).GetI();
}
@@ -1751,7 +1753,7 @@
static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticLongMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
va_end(ap);
@@ -1759,13 +1761,13 @@
}
static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
}
static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
}
@@ -1773,7 +1775,7 @@
static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
va_end(ap);
@@ -1781,13 +1783,13 @@
}
static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
}
static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, nullptr, mid, args).GetF();
}
@@ -1795,7 +1797,7 @@
static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
va_end(ap);
@@ -1803,13 +1805,13 @@
}
static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
}
static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
return InvokeWithJValues(soa, nullptr, mid, args).GetD();
}
@@ -1817,20 +1819,20 @@
static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
- CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethod, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeWithVarArgs(soa, nullptr, mid, ap);
va_end(ap);
}
static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodV, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeWithVarArgs(soa, nullptr, mid, args);
}
static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
- CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodA, mid);
+ CHECK_NON_NULL_ARGUMENT(mid);
ScopedObjectAccess soa(env);
InvokeWithJValues(soa, nullptr, mid, args);
}
@@ -1859,26 +1861,26 @@
}
static jsize GetStringLength(JNIEnv* env, jstring java_string) {
- CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string);
+ CHECK_NON_NULL_ARGUMENT(java_string);
ScopedObjectAccess soa(env);
return soa.Decode<mirror::String*>(java_string)->GetLength();
}
static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
- CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string);
+ CHECK_NON_NULL_ARGUMENT(java_string);
ScopedObjectAccess soa(env);
return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
}
static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
jchar* buf) {
- CHECK_NON_NULL_ARGUMENT(GetStringRegion, java_string);
+ CHECK_NON_NULL_ARGUMENT(java_string);
ScopedObjectAccess soa(env);
mirror::String* s = soa.Decode<mirror::String*>(java_string);
if (start < 0 || length < 0 || start + length > s->GetLength()) {
ThrowSIOOBE(soa, start, length, s->GetLength());
} else {
- CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
+ CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
memcpy(buf, chars + start, length * sizeof(jchar));
}
@@ -1886,20 +1888,20 @@
static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
char* buf) {
- CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
+ CHECK_NON_NULL_ARGUMENT(java_string);
ScopedObjectAccess soa(env);
mirror::String* s = soa.Decode<mirror::String*>(java_string);
if (start < 0 || length < 0 || start + length > s->GetLength()) {
ThrowSIOOBE(soa, start, length, s->GetLength());
} else {
- CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringUTFRegion, length, buf);
+ CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
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) {
- CHECK_NON_NULL_ARGUMENT(GetStringChars, java_string);
+ CHECK_NON_NULL_ARGUMENT(java_string);
ScopedObjectAccess soa(env);
mirror::String* s = soa.Decode<mirror::String*>(java_string);
mirror::CharArray* chars = s->GetCharArray();
@@ -1918,7 +1920,7 @@
}
static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
- CHECK_NON_NULL_ARGUMENT(ReleaseStringChars, java_string);
+ CHECK_NON_NULL_ARGUMENT(java_string);
delete[] chars;
ScopedObjectAccess soa(env);
UnpinPrimitiveArray(soa, soa.Decode<mirror::String*>(java_string)->GetCharArray());
@@ -1955,7 +1957,7 @@
}
static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
- CHECK_NON_NULL_ARGUMENT(GetArrayLength, java_array);
+ CHECK_NON_NULL_ARGUMENT(java_array);
ScopedObjectAccess soa(env);
mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
if (UNLIKELY(!obj->IsArrayInstance())) {
@@ -1966,7 +1968,7 @@
}
static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
- CHECK_NON_NULL_ARGUMENT(GetObjectArrayElement, java_array);
+ CHECK_NON_NULL_ARGUMENT(java_array);
ScopedObjectAccess soa(env);
mirror::ObjectArray<mirror::Object>* array =
soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
@@ -1975,7 +1977,7 @@
static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
jobject java_value) {
- CHECK_NON_NULL_ARGUMENT(SetObjectArrayElement, java_array);
+ CHECK_NON_NULL_ARGUMENT(java_array);
ScopedObjectAccess soa(env);
mirror::ObjectArray<mirror::Object>* array =
soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
@@ -2070,7 +2072,7 @@
}
static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayCritical, java_array);
+ CHECK_NON_NULL_ARGUMENT(java_array);
ScopedObjectAccess soa(env);
mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
gc::Heap* heap = Runtime::Current()->GetHeap();
@@ -2087,54 +2089,54 @@
}
static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* elements, jint mode) {
- CHECK_NON_NULL_ARGUMENT(ReleasePrimitiveArrayCritical, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ReleasePrimitiveArray(env, array, elements, mode);
}
static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetBooleanArrayElements, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ScopedObjectAccess soa(env);
return GetPrimitiveArray<jbooleanArray, jboolean*, mirror::BooleanArray>(soa, array, is_copy);
}
static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetByteArrayElements, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ScopedObjectAccess soa(env);
return GetPrimitiveArray<jbyteArray, jbyte*, mirror::ByteArray>(soa, array, is_copy);
}
static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetCharArrayElements, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ScopedObjectAccess soa(env);
return GetPrimitiveArray<jcharArray, jchar*, mirror::CharArray>(soa, array, is_copy);
}
static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetDoubleArrayElements, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ScopedObjectAccess soa(env);
return GetPrimitiveArray<jdoubleArray, jdouble*, mirror::DoubleArray>(soa, array, is_copy);
}
static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetFloatArrayElements, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ScopedObjectAccess soa(env);
return GetPrimitiveArray<jfloatArray, jfloat*, mirror::FloatArray>(soa, array, is_copy);
}
static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetIntArrayElements, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ScopedObjectAccess soa(env);
return GetPrimitiveArray<jintArray, jint*, mirror::IntArray>(soa, array, is_copy);
}
static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetLongArrayElements, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ScopedObjectAccess soa(env);
return GetPrimitiveArray<jlongArray, jlong*, mirror::LongArray>(soa, array, is_copy);
}
static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
- CHECK_NON_NULL_ARGUMENT(GetShortArrayElements, array);
+ CHECK_NON_NULL_ARGUMENT(array);
ScopedObjectAccess soa(env);
return GetPrimitiveArray<jshortArray, jshort*, mirror::ShortArray>(soa, array, is_copy);
}
@@ -2290,7 +2292,7 @@
JniAbortF("RegisterNatives", "negative method count: %d", method_count);
return JNI_ERR; // Not reached.
}
- CHECK_NON_NULL_ARGUMENT(RegisterNatives, java_class);
+ CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class);
ScopedObjectAccess soa(env);
mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
if (UNLIKELY(method_count == 0)) {
@@ -2298,7 +2300,7 @@
<< PrettyDescriptor(c);
return JNI_OK;
}
- CHECK_NON_NULL_ARGUMENT(RegisterNatives, methods);
+ CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods);
for (jint i = 0; i < method_count; ++i) {
const char* name = methods[i].name;
const char* sig = methods[i].signature;
@@ -2335,7 +2337,7 @@
}
static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
- CHECK_NON_NULL_ARGUMENT(UnregisterNatives, java_class);
+ CHECK_NON_NULL_ARGUMENT(java_class);
ScopedObjectAccess soa(env);
mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
@@ -2358,7 +2360,7 @@
}
static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
- CHECK_NON_NULL_ARGUMENT(MonitorEnter, java_object);
+ CHECK_NON_NULL_ARGUMENT(java_object);
ScopedObjectAccess soa(env);
mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
o = o->MonitorEnter(soa.Self());
@@ -2370,7 +2372,7 @@
}
static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
- CHECK_NON_NULL_ARGUMENT(MonitorExit, java_object);
+ CHECK_NON_NULL_ARGUMENT(java_object);
ScopedObjectAccess soa(env);
mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
o->MonitorExit(soa.Self());
@@ -2382,7 +2384,7 @@
}
static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
- CHECK_NON_NULL_ARGUMENT(GetJavaVM, vm);
+ CHECK_NON_NULL_ARGUMENT(vm);
Runtime* runtime = Runtime::Current();
if (runtime != nullptr) {
*vm = runtime->GetJavaVM();
@@ -2422,7 +2424,7 @@
}
static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
- CHECK_NON_NULL_ARGUMENT(GetObjectRefType, java_object);
+ CHECK_NON_NULL_ARGUMENT(java_object);
// Do we definitely know what kind of reference this is?
IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
@@ -2543,12 +2545,12 @@
static void GetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
jsize start, jsize length, JavaT* buf)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayRegion, java_array);
+ CHECK_NON_NULL_ARGUMENT(java_array);
ArrayT* array = soa.Decode<ArrayT*>(java_array);
if (start < 0 || length < 0 || start + length > array->GetLength()) {
ThrowAIOOBE(soa, array, start, length, "src");
} else {
- CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
+ CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
JavaT* data = array->GetData();
memcpy(buf, data + start, length * sizeof(JavaT));
}
@@ -2558,12 +2560,12 @@
static void SetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
jsize start, jsize length, const JavaT* buf)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK_NON_NULL_ARGUMENT(SetPrimitiveArrayRegion, java_array);
+ CHECK_NON_NULL_ARGUMENT(java_array);
ArrayT* array = soa.Decode<ArrayT*>(java_array);
if (start < 0 || length < 0 || start + length > array->GetLength()) {
ThrowAIOOBE(soa, array, start, length, "dst");
} else {
- CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
+ CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
JavaT* data = array->GetData();
memcpy(data + start, buf, length * sizeof(JavaT));
}
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index 3d2fd7b..7f974d0 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -27,10 +27,11 @@
namespace art {
namespace mirror {
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline size_t Array::SizeOf() {
// This is safe from overflow because the array was already allocated, so we know it's sane.
- size_t component_size = GetClass<kVerifyFlags>()->GetComponentSize();
+ size_t component_size =
+ GetClass<kVerifyFlags, kDoReadBarrier>()->template GetComponentSize<kDoReadBarrier>();
// Don't need to check this since we already check this in GetClass.
int32_t component_count =
GetLength<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>();
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 772d303..6bfd5c8 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -41,7 +41,7 @@
const SirtRef<IntArray>& dimensions)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
size_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
int32_t GetLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc
index f91cab1..7b0b94c 100644
--- a/runtime/mirror/art_field.cc
+++ b/runtime/mirror/art_field.cc
@@ -19,6 +19,7 @@
#include "art_field-inl.h"
#include "gc/accounting/card_table-inl.h"
#include "object-inl.h"
+#include "object_array-inl.h"
#include "object_utils.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
@@ -69,5 +70,25 @@
}
}
+// TODO: we could speed up the search if fields are ordered by offsets.
+ArtField* ArtField::FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset) {
+ DCHECK(klass != nullptr);
+ ObjectArray<ArtField>* instance_fields = klass->GetIFields();
+ if (instance_fields != nullptr) {
+ for (int32_t i = 0, e = instance_fields->GetLength(); i < e; ++i) {
+ mirror::ArtField* field = instance_fields->GetWithoutChecks(i);
+ if (field->GetOffset().Uint32Value() == field_offset) {
+ return field;
+ }
+ }
+ }
+ // We did not find field in the class: look into superclass.
+ if (klass->GetSuperClass() != NULL) {
+ return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset);
+ } else {
+ return nullptr;
+ }
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h
index 0daa838..ba70cc6 100644
--- a/runtime/mirror/art_field.h
+++ b/runtime/mirror/art_field.h
@@ -132,6 +132,10 @@
return (GetAccessFlags() & kAccVolatile) != 0;
}
+ // Returns an instance field with this offset in the given class or nullptr if not found.
+ static ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
private:
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
// The class we are a part of
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index f3303a8..726004b 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -315,13 +315,13 @@
} else {
(*art_portable_invoke_stub)(this, args, args_size, self, result, shorty[0]);
}
- if (UNLIKELY(reinterpret_cast<intptr_t>(self->GetException(NULL)) == -1)) {
- // Unusual case where we were running LLVM generated code and an
+ if (UNLIKELY(self->GetException(nullptr) == Thread::GetDeoptimizationException())) {
+ // Unusual case where we were running generated code and an
// exception was thrown to force the activations to be removed from the
// stack. Continue execution in the interpreter.
self->ClearException();
ShadowFrame* shadow_frame = self->GetAndClearDeoptimizationShadowFrame(result);
- self->SetTopOfStack(NULL, 0);
+ self->SetTopOfStack(nullptr, 0);
self->SetTopOfShadowStack(shadow_frame);
interpreter::EnterInterpreterFromDeoptimize(self, shadow_frame, result);
}
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index d684266..4462036 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -426,7 +426,9 @@
static void SetClass(Class* java_lang_reflect_ArtMethod);
+ template <bool kDoReadBarrier = true>
static Class* GetJavaLangReflectArtMethod() {
+ // This does not need a RB because it is a root.
return java_lang_reflect_ArtMethod_;
}
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 025e62a..3c02aa0 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -478,6 +478,19 @@
VisitStaticFieldsReferences<kVisitClass>(this, visitor);
}
+template<bool kDoReadBarrier>
+bool Class::IsArtFieldClass() {
+ Class* java_lang_Class = GetClass<kVerifyNone, kDoReadBarrier>();
+ Class* java_lang_reflect_ArtField =
+ java_lang_Class->GetInstanceField(0)->GetClass<kVerifyNone, kDoReadBarrier>();
+ return this == java_lang_reflect_ArtField;
+}
+
+template<bool kDoReadBarrier>
+bool Class::IsArtMethodClass() {
+ return this == ArtMethod::GetJavaLangReflectArtMethod<kDoReadBarrier>();
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 6dbb29d..ad86e1f 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -328,16 +328,6 @@
return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this);
}
-bool Class::IsArtFieldClass() {
- Class* java_lang_Class = GetClass();
- Class* java_lang_reflect_ArtField = java_lang_Class->GetInstanceField(0)->GetClass();
- return this == java_lang_reflect_ArtField;
-}
-
-bool Class::IsArtMethodClass() {
- return this == ArtMethod::GetJavaLangReflectArtMethod();
-}
-
void Class::SetClassLoader(ClassLoader* new_class_loader) {
if (Runtime::Current()->IsActiveTransaction()) {
SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false);
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index d955b97..226dee0 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -364,9 +364,9 @@
return depth;
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
bool IsArrayClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetComponentType<kVerifyFlags>() != NULL;
+ return GetComponentType<kVerifyFlags, kDoReadBarrier>() != NULL;
}
bool IsClassClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -375,17 +375,19 @@
bool IsThrowableClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ template<bool kDoReadBarrier = true>
bool IsArtFieldClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ template<bool kDoReadBarrier = true>
bool IsArtMethodClass();
static MemberOffset ComponentTypeOffset() {
return OFFSET_OF_OBJECT_MEMBER(Class, component_type_);
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
Class* GetComponentType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetFieldObject<Class, kVerifyFlags>(ComponentTypeOffset(), false);
+ return GetFieldObject<Class, kVerifyFlags, kDoReadBarrier>(ComponentTypeOffset(), false);
}
void SetComponentType(Class* new_component_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -395,8 +397,10 @@
SetFieldObject<false, false>(ComponentTypeOffset(), new_component_type, false);
}
+ template<bool kDoReadBarrier = true>
size_t GetComponentSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return Primitive::ComponentSize(GetComponentType()->GetPrimitiveType());
+ return Primitive::ComponentSize(
+ GetComponentType<kDefaultVerifyFlags, kDoReadBarrier>()->GetPrimitiveType());
}
bool IsObjectClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -427,7 +431,7 @@
return IsClassClass() || IsArrayClass();
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
uint32_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), false);
}
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index b195dea..04517ec 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -34,9 +34,10 @@
namespace art {
namespace mirror {
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline Class* Object::GetClass() {
- return GetFieldObject<Class, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
+ return GetFieldObject<Class, kVerifyFlags, kDoReadBarrier>(
+ OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
}
template<VerifyObjectFlags kVerifyFlags>
@@ -105,18 +106,45 @@
#endif
}
-inline void Object::SetReadBarrierPointer(Object* rb_pointer) {
+inline void Object::SetReadBarrierPointer(Object* rb_ptr) {
#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
DCHECK(kUseBakerOrBrooksReadBarrier);
// We don't mark the card as this occurs as part of object allocation. Not all objects have
// backing cards, such as large objects.
SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
- OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_pointer, false);
+ OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr, false);
#else
LOG(FATAL) << "Unreachable";
#endif
}
+inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) {
+#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
+ DCHECK(kUseBakerOrBrooksReadBarrier);
+ MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
+ byte* raw_addr = reinterpret_cast<byte*>(this) + offset.SizeValue();
+ HeapReference<Object>* ref = reinterpret_cast<HeapReference<Object>*>(raw_addr);
+ HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
+ HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
+ uint32_t expected_val = expected_ref.reference_;
+ uint32_t new_val;
+ do {
+ uint32_t old_val = ref->reference_;
+ if (old_val != expected_val) {
+ // Lost the race.
+ return false;
+ }
+ new_val = new_ref.reference_;
+ } while (!__sync_bool_compare_and_swap(
+ reinterpret_cast<uint32_t*>(raw_addr), expected_val, new_val));
+ DCHECK_EQ(new_val, ref->reference_);
+ return true;
+#else
+ LOG(FATAL) << "Unreachable";
+ return false;
+#endif
+}
+
inline void Object::AssertReadBarrierPointer() const {
if (kUseBakerReadBarrier) {
Object* obj = const_cast<Object*>(this);
@@ -147,16 +175,17 @@
return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
}
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline bool Object::IsClass() {
- Class* java_lang_Class = GetClass<kVerifyFlags>()->GetClass();
- return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ==
+ Class* java_lang_Class =
+ GetClass<kVerifyFlags, kDoReadBarrier>()->template GetClass<kVerifyFlags, kDoReadBarrier>();
+ return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis), kDoReadBarrier>() ==
java_lang_Class;
}
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline Class* Object::AsClass() {
- DCHECK(IsClass<kVerifyFlags>());
+ DCHECK((IsClass<kVerifyFlags, kDoReadBarrier>()));
return down_cast<Class*>(this);
}
@@ -173,14 +202,15 @@
return down_cast<ObjectArray<T>*>(this);
}
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline bool Object::IsArrayInstance() {
- return GetClass<kVerifyFlags>()->IsArrayClass();
+ return GetClass<kVerifyFlags, kDoReadBarrier>()->
+ template IsArrayClass<kVerifyFlags, kDoReadBarrier>();
}
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline bool Object::IsArtField() {
- return GetClass<kVerifyFlags>()->IsArtFieldClass();
+ return GetClass<kVerifyFlags, kDoReadBarrier>()->template IsArtFieldClass<kDoReadBarrier>();
}
template<VerifyObjectFlags kVerifyFlags>
@@ -189,9 +219,9 @@
return down_cast<ArtField*>(this);
}
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline bool Object::IsArtMethod() {
- return GetClass<kVerifyFlags>()->IsArtMethodClass();
+ return GetClass<kVerifyFlags, kDoReadBarrier>()->template IsArtMethodClass<kDoReadBarrier>();
}
template<VerifyObjectFlags kVerifyFlags>
@@ -211,9 +241,9 @@
return down_cast<Reference*>(this);
}
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline Array* Object::AsArray() {
- DCHECK(IsArrayInstance<kVerifyFlags>());
+ DCHECK((IsArrayInstance<kVerifyFlags, kDoReadBarrier>()));
return down_cast<Array*>(this);
}
@@ -339,20 +369,21 @@
return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
}
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
inline size_t Object::SizeOf() {
size_t result;
constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
- if (IsArrayInstance<kVerifyFlags>()) {
- result = AsArray<kNewFlags>()->template SizeOf<kNewFlags>();
- } else if (IsClass<kNewFlags>()) {
- result = AsClass<kNewFlags>()->template SizeOf<kNewFlags>();
+ if (IsArrayInstance<kVerifyFlags, kDoReadBarrier>()) {
+ result = AsArray<kNewFlags, kDoReadBarrier>()->template SizeOf<kNewFlags, kDoReadBarrier>();
+ } else if (IsClass<kNewFlags, kDoReadBarrier>()) {
+ result = AsClass<kNewFlags, kDoReadBarrier>()->template SizeOf<kNewFlags, kDoReadBarrier>();
} else {
- result = GetClass<kNewFlags>()->GetObjectSize();
+ result = GetClass<kNewFlags, kDoReadBarrier>()->GetObjectSize();
}
- DCHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(GetClass<kNewFlags>());
- DCHECK(!IsArtField<kNewFlags>() || result == sizeof(ArtField));
- DCHECK(!IsArtMethod<kNewFlags>() || result == sizeof(ArtMethod));
+ DCHECK_GE(result, sizeof(Object))
+ << " class=" << PrettyTypeOf(GetClass<kNewFlags, kDoReadBarrier>());
+ DCHECK(!(IsArtField<kNewFlags, kDoReadBarrier>()) || result == sizeof(ArtField));
+ DCHECK(!(IsArtMethod<kNewFlags, kDoReadBarrier>()) || result == sizeof(ArtMethod));
return result;
}
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index fd31dfb..370b3b8 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -72,14 +72,16 @@
return OFFSET_OF_OBJECT_MEMBER(Object, klass_);
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
Class* GetClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
void SetClass(Class* new_klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Object* GetReadBarrierPointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetReadBarrierPointer(Object* rb_pointer) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetReadBarrierPointer(Object* rb_ptr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void AssertReadBarrierPointer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// The verifier treats all interfaces as java.lang.Object and relies on runtime checks in
@@ -89,7 +91,7 @@
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool InstanceOf(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
size_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Object* Clone(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -116,9 +118,9 @@
void Wait(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void Wait(Thread* self, int64_t timeout, int32_t nanos) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
bool IsClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
Class* AsClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -126,9 +128,9 @@
template<class T, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ObjectArray<T>* AsObjectArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
bool IsArrayInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
Array* AsArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -161,12 +163,12 @@
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Throwable* AsThrowable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
bool IsArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ArtMethod* AsArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true>
bool IsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ArtField* AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/catch_finder.cc b/runtime/quick_exception_handler.cc
similarity index 67%
rename from runtime/catch_finder.cc
rename to runtime/quick_exception_handler.cc
index f0293d7..d5844b6 100644
--- a/runtime/catch_finder.cc
+++ b/runtime/quick_exception_handler.cc
@@ -14,37 +14,37 @@
* limitations under the License.
*/
-#include "catch_finder.h"
+#include "quick_exception_handler.h"
+
#include "catch_block_stack_visitor.h"
+#include "deoptimize_stack_visitor.h"
+#include "entrypoints/entrypoint_utils.h"
+#include "sirt_ref-inl.h"
namespace art {
-CatchFinder::CatchFinder(Thread* self, const ThrowLocation& throw_location,
- mirror::Throwable* exception, bool is_deoptimization)
- : self_(self), context_(self->GetLongJumpContext()),
- exception_(exception), is_deoptimization_(is_deoptimization), throw_location_(throw_location),
+QuickExceptionHandler::QuickExceptionHandler(Thread* self, bool is_deoptimization)
+ : self_(self), context_(self->GetLongJumpContext()), is_deoptimization_(is_deoptimization),
method_tracing_active_(is_deoptimization ||
Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled()),
- handler_quick_frame_(nullptr), handler_quick_frame_pc_(0),
- handler_dex_pc_(0), clear_exception_(false), top_shadow_frame_(nullptr),
- handler_frame_id_(kInvalidFrameId) {
- // Exception not in root sets, can't allow GC.
- last_no_assert_suspension_cause_ = self->StartAssertNoThreadSuspension("Finding catch block");
+ handler_quick_frame_(nullptr), handler_quick_frame_pc_(0), handler_dex_pc_(0),
+ clear_exception_(false), top_shadow_frame_(nullptr), handler_frame_id_(kInvalidFrameId) {
}
-void CatchFinder::FindCatch() {
+void QuickExceptionHandler::FindCatch(const ThrowLocation& throw_location,
+ mirror::Throwable* exception) {
+ DCHECK(!is_deoptimization_);
+ SirtRef<mirror::Throwable> exception_ref(self_, exception);
+
// Walk the stack to find catch handler or prepare for deoptimization.
- CatchBlockStackVisitor visitor(self_, context_, exception_, is_deoptimization_, this);
+ CatchBlockStackVisitor visitor(self_, context_, exception_ref, this);
visitor.WalkStack(true);
mirror::ArtMethod* catch_method = *handler_quick_frame_;
- if (catch_method == nullptr) {
- if (kDebugExceptionDelivery) {
+ if (kDebugExceptionDelivery) {
+ if (catch_method == nullptr) {
LOG(INFO) << "Handler is upcall";
- }
- } else {
- CHECK(!is_deoptimization_);
- if (kDebugExceptionDelivery) {
+ } else {
const DexFile& dex_file = *catch_method->GetDeclaringClass()->GetDexCache()->GetDexFile();
int line_number = dex_file.GetLineNumFromPC(catch_method, handler_dex_pc_);
LOG(INFO) << "Handler: " << PrettyMethod(catch_method) << " (line: " << line_number << ")";
@@ -55,17 +55,23 @@
DCHECK(!self_->IsExceptionPending());
} else {
// Put exception back in root set with clear throw location.
- self_->SetException(ThrowLocation(), exception_);
+ self_->SetException(ThrowLocation(), exception_ref.get());
}
- self_->EndAssertNoThreadSuspension(last_no_assert_suspension_cause_);
- // Do instrumentation events after allowing thread suspension again.
- if (!is_deoptimization_) {
- // The debugger may suspend this thread and walk its stack. Let's do this before popping
- // instrumentation frames.
- instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
- instrumentation->ExceptionCaughtEvent(self_, throw_location_, catch_method, handler_dex_pc_,
- exception_);
- }
+ // The debugger may suspend this thread and walk its stack. Let's do this before popping
+ // instrumentation frames.
+ instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
+ instrumentation->ExceptionCaughtEvent(self_, throw_location, catch_method, handler_dex_pc_,
+ exception_ref.get());
+}
+
+void QuickExceptionHandler::DeoptimizeStack() {
+ DCHECK(is_deoptimization_);
+
+ DeoptimizeStackVisitor visitor(self_, context_, this);
+ visitor.WalkStack(true);
+
+ // Restore deoptimization exception
+ self_->SetException(ThrowLocation(), Thread::GetDeoptimizationException());
}
// Unwinds all instrumentation stack frame prior to catch handler or upcall.
@@ -105,7 +111,7 @@
DISALLOW_COPY_AND_ASSIGN(InstrumentationStackVisitor);
};
-void CatchFinder::UpdateInstrumentationStack() {
+void QuickExceptionHandler::UpdateInstrumentationStack() {
if (method_tracing_active_) {
InstrumentationStackVisitor visitor(self_, is_deoptimization_, handler_frame_id_);
visitor.WalkStack(true);
@@ -118,7 +124,7 @@
}
}
-void CatchFinder::DoLongJump() {
+void QuickExceptionHandler::DoLongJump() {
if (is_deoptimization_) {
// TODO: proper return value.
self_->SetDeoptimizationShadowFrame(top_shadow_frame_);
diff --git a/runtime/catch_finder.h b/runtime/quick_exception_handler.h
similarity index 76%
rename from runtime/catch_finder.h
rename to runtime/quick_exception_handler.h
index ebbafe2..d06ce7c 100644
--- a/runtime/catch_finder.h
+++ b/runtime/quick_exception_handler.h
@@ -14,29 +14,39 @@
* limitations under the License.
*/
-#ifndef ART_RUNTIME_CATCH_FINDER_H_
-#define ART_RUNTIME_CATCH_FINDER_H_
+#ifndef ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_
+#define ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_
-#include "mirror/art_method-inl.h"
-#include "thread.h"
+#include "base/logging.h"
+#include "base/mutex.h"
namespace art {
+namespace mirror {
+class ArtMethod;
+class Throwable;
+} // namespace mirror
+class Context;
+class Thread;
+class ThrowLocation;
+class ShadowFrame;
+
static constexpr bool kDebugExceptionDelivery = false;
static constexpr size_t kInvalidFrameId = 0xffffffff;
// Manages exception delivery for Quick backend. Not used by Portable backend.
-class CatchFinder {
+class QuickExceptionHandler {
public:
- CatchFinder(Thread* self, const ThrowLocation& throw_location, mirror::Throwable* exception,
- bool is_deoptimization)
+ QuickExceptionHandler(Thread* self, bool is_deoptimization)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ~CatchFinder() {
+ ~QuickExceptionHandler() {
LOG(FATAL) << "UNREACHABLE"; // Expected to take long jump.
}
- void FindCatch() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void FindCatch(const ThrowLocation& throw_location, mirror::Throwable* exception)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void DeoptimizeStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void UpdateInstrumentationStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void DoLongJump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -67,14 +77,9 @@
private:
Thread* const self_;
Context* const context_;
- mirror::Throwable* const exception_;
const bool is_deoptimization_;
- // Location of the throw.
- const ThrowLocation& throw_location_;
// Is method tracing active?
const bool method_tracing_active_;
- // Support for nesting no thread suspension checks.
- const char* last_no_assert_suspension_cause_;
// Quick frame with found handler or last frame if no handler found.
mirror::ArtMethod** handler_quick_frame_;
// PC to branch to for the handler.
@@ -88,8 +93,8 @@
// Frame id of the catch handler or the upcall.
size_t handler_frame_id_;
- DISALLOW_COPY_AND_ASSIGN(CatchFinder);
+ DISALLOW_COPY_AND_ASSIGN(QuickExceptionHandler);
};
} // namespace art
-#endif // ART_RUNTIME_CATCH_FINDER_H_
+#endif // ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_
diff --git a/runtime/scoped_thread_state_change.h b/runtime/scoped_thread_state_change.h
index 404c616..7698d6a 100644
--- a/runtime/scoped_thread_state_change.h
+++ b/runtime/scoped_thread_state_change.h
@@ -38,23 +38,18 @@
Runtime* runtime = Runtime::Current();
CHECK(runtime == NULL || !runtime->IsStarted() || runtime->IsShuttingDown(self_));
} else {
- bool runnable_transition;
DCHECK_EQ(self, Thread::Current());
// Read state without locks, ok as state is effectively thread local and we're not interested
// in the suspend count (this will be handled in the runnable transitions).
old_thread_state_ = self->GetState();
- runnable_transition = old_thread_state_ == kRunnable || new_thread_state == kRunnable;
- if (!runnable_transition) {
- // A suspended transition to another effectively suspended transition, ok to use Unsafe.
- self_->SetState(new_thread_state);
- }
-
- if (runnable_transition && old_thread_state_ != new_thread_state) {
+ if (old_thread_state_ != new_thread_state) {
if (new_thread_state == kRunnable) {
self_->TransitionFromSuspendedToRunnable();
- } else {
- DCHECK_EQ(old_thread_state_, kRunnable);
+ } else if (old_thread_state_ == kRunnable) {
self_->TransitionFromRunnableToSuspended(new_thread_state);
+ } else {
+ // A suspended transition to another effectively suspended transition, ok to use Unsafe.
+ self_->SetState(new_thread_state);
}
}
}
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 998579d..095404f 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -32,7 +32,6 @@
#include "arch/context.h"
#include "base/mutex.h"
-#include "catch_finder.h"
#include "class_linker.h"
#include "class_linker-inl.h"
#include "cutils/atomic.h"
@@ -54,6 +53,7 @@
#include "mirror/stack_trace_element.h"
#include "monitor.h"
#include "object_utils.h"
+#include "quick_exception_handler.h"
#include "reflection.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
@@ -1841,7 +1841,7 @@
// Don't leave exception visible while we try to find the handler, which may cause class
// resolution.
ClearException();
- bool is_deoptimization = (exception == reinterpret_cast<mirror::Throwable*>(-1));
+ bool is_deoptimization = (exception == GetDeoptimizationException());
if (kDebugExceptionDelivery) {
if (!is_deoptimization) {
mirror::String* msg = exception->GetDetailMessage();
@@ -1852,10 +1852,14 @@
DumpStack(LOG(INFO) << "Deoptimizing: ");
}
}
- CatchFinder catch_finder(this, throw_location, exception, is_deoptimization);
- catch_finder.FindCatch();
- catch_finder.UpdateInstrumentationStack();
- catch_finder.DoLongJump();
+ QuickExceptionHandler exception_handler(this, is_deoptimization);
+ if (is_deoptimization) {
+ exception_handler.DeoptimizeStack();
+ } else {
+ exception_handler.FindCatch(throw_location, exception);
+ }
+ exception_handler.UpdateInstrumentationStack();
+ exception_handler.DoLongJump();
LOG(FATAL) << "UNREACHABLE";
}
@@ -2060,7 +2064,7 @@
if (tlsPtr_.opeer != nullptr) {
visitor(&tlsPtr_.opeer, arg, thread_id, kRootThreadObject);
}
- if (tlsPtr_.exception != nullptr) {
+ if (tlsPtr_.exception != nullptr && tlsPtr_.exception != GetDeoptimizationException()) {
visitor(reinterpret_cast<mirror::Object**>(&tlsPtr_.exception), arg, thread_id, kRootNativeStack);
}
tlsPtr_.throw_location.VisitRoots(visitor, arg);
diff --git a/runtime/thread.h b/runtime/thread.h
index d25bbe9..e5e4cae 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -686,6 +686,11 @@
return tlsPtr_.single_step_control;
}
+ // Returns the fake exception used to activate deoptimization.
+ static mirror::Throwable* GetDeoptimizationException() {
+ return reinterpret_cast<mirror::Throwable*>(-1);
+ }
+
void SetDeoptimizationShadowFrame(ShadowFrame* sf);
void SetDeoptimizationReturnValue(const JValue& ret_val);
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 535c76d..91170f0 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -1176,8 +1176,11 @@
// it's effectively considered initialized the instant we reach here (in the sense that we
// can return without doing anything or call virtual methods).
{
- const RegType& reg_type = reg_types_.FromDescriptor(class_loader_->get(), descriptor,
- false);
+ const RegType& reg_type = ResolveClassAndCheckAccess(iterator.GetTypeIdx());
+ if (!reg_type.IsNonZeroReferenceTypes()) {
+ DCHECK(HasFailures());
+ return false;
+ }
reg_line->SetRegisterType(arg_start + cur_arg, reg_type);
}
break;
@@ -2865,11 +2868,7 @@
common_super = ®_types_.JavaLangThrowable(false);
} else {
const RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex());
- if (common_super == NULL) {
- // Unconditionally assign for the first handler. We don't assert this is a Throwable
- // as that is caught at runtime
- common_super = &exception;
- } else if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception)) {
+ if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception)) {
if (exception.IsUnresolvedTypes()) {
// We don't know enough about the type. Fail here and let runtime handle it.
Fail(VERIFY_ERROR_NO_CLASS) << "unresolved exception class " << exception;
@@ -2878,6 +2877,8 @@
Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unexpected non-exception class " << exception;
return reg_types_.Conflict();
}
+ } else if (common_super == nullptr) {
+ common_super = &exception;
} else if (common_super->Equals(exception)) {
// odd case, but nothing to do
} else {
@@ -3596,29 +3597,6 @@
}
}
-// Look for an instance field with this offset.
-// TODO: we may speed up the search if offsets are sorted by doing a quick search.
-static mirror::ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ObjectArray<mirror::ArtField>* instance_fields = klass->GetIFields();
- if (instance_fields != NULL) {
- for (int32_t i = 0, e = instance_fields->GetLength(); i < e; ++i) {
- mirror::ArtField* field = instance_fields->Get(i);
- if (field->GetOffset().Uint32Value() == field_offset) {
- return field;
- }
- }
- }
- // We did not find field in class: look into superclass.
- if (klass->GetSuperClass() != NULL) {
- return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset);
- } else {
- VLOG(verifier) << "Failed to find instance field at offset '" << field_offset
- << "' from '" << PrettyDescriptor(klass) << "'";
- return nullptr;
- }
-}
-
mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
RegisterLine* reg_line) {
DCHECK(inst->Opcode() == Instruction::IGET_QUICK ||
@@ -3633,7 +3611,13 @@
return nullptr;
}
uint32_t field_offset = static_cast<uint32_t>(inst->VRegC_22c());
- return FindInstanceFieldWithOffset(object_type.GetClass(), field_offset);
+ mirror::ArtField* f = mirror::ArtField::FindInstanceFieldWithOffset(object_type.GetClass(),
+ field_offset);
+ if (f == nullptr) {
+ VLOG(verifier) << "Failed to find instance field at offset '" << field_offset
+ << "' from '" << PrettyDescriptor(object_type.GetClass()) << "'";
+ }
+ return f;
}
void MethodVerifier::VerifyIGetQuick(const Instruction* inst, const RegType& insn_type,