diff options
| author | 2015-05-11 18:04:09 +0000 | |
|---|---|---|
| committer | 2015-05-11 18:04:10 +0000 | |
| commit | 1d316adafda81cb2f30e210d3d108b97c7c11f15 (patch) | |
| tree | 57aa3ebf536ce612281523ce385cedf583afa93a /compiler | |
| parent | bd0cfef567012fa6c75243d9157ddceaab7cdaac (diff) | |
| parent | 1cc71ebf333ca323ae0e130fefbce4593e385c10 (diff) | |
Merge "Insert a read barrier in the JNI bridge."
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/jni/quick/jni_compiler.cc | 46 | ||||
| -rw-r--r-- | compiler/oat_test.cc | 2 |
2 files changed, 46 insertions, 2 deletions
diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc index 6f2cb25911..a06303d23e 100644 --- a/compiler/jni/quick/jni_compiler.cc +++ b/compiler/jni/quick/jni_compiler.cc @@ -138,7 +138,8 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver* driver, FrameOffset handle_scope_offset = main_jni_conv->CurrentParamHandleScopeEntryOffset(); // Check handle scope offset is within frame CHECK_LT(handle_scope_offset.Uint32Value(), frame_size); - // TODO: Insert the read barrier for this load. + // Note this LoadRef() already includes the heap poisoning negation. + // Note this LoadRef() does not include read barrier. It will be handled below. __ LoadRef(main_jni_conv->InterproceduralScratchRegister(), mr_conv->MethodRegister(), mirror::ArtMethod::DeclaringClassOffset()); __ VerifyObject(main_jni_conv->InterproceduralScratchRegister(), false); @@ -189,6 +190,49 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver* driver, size_t current_out_arg_size = main_out_arg_size; __ IncreaseFrameSize(main_out_arg_size); + // Call the read barrier for the declaring class loaded from the method for a static call. + // Note that we always have outgoing param space available for at least two params. + if (kUseReadBarrier && is_static) { + ThreadOffset<4> read_barrier32 = QUICK_ENTRYPOINT_OFFSET(4, pReadBarrierJni); + ThreadOffset<8> read_barrier64 = QUICK_ENTRYPOINT_OFFSET(8, pReadBarrierJni); + main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size)); + main_jni_conv->Next(); // Skip JNIEnv. + FrameOffset class_handle_scope_offset = main_jni_conv->CurrentParamHandleScopeEntryOffset(); + main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size)); + // Pass the handle for the class as the first argument. + if (main_jni_conv->IsCurrentParamOnStack()) { + FrameOffset out_off = main_jni_conv->CurrentParamStackOffset(); + __ CreateHandleScopeEntry(out_off, class_handle_scope_offset, + mr_conv->InterproceduralScratchRegister(), + false); + } else { + ManagedRegister out_reg = main_jni_conv->CurrentParamRegister(); + __ CreateHandleScopeEntry(out_reg, class_handle_scope_offset, + ManagedRegister::NoRegister(), false); + } + main_jni_conv->Next(); + // Pass the current thread as the second argument and call. + if (main_jni_conv->IsCurrentParamInRegister()) { + __ GetCurrentThread(main_jni_conv->CurrentParamRegister()); + if (is_64_bit_target) { + __ Call(main_jni_conv->CurrentParamRegister(), Offset(read_barrier64), + main_jni_conv->InterproceduralScratchRegister()); + } else { + __ Call(main_jni_conv->CurrentParamRegister(), Offset(read_barrier32), + main_jni_conv->InterproceduralScratchRegister()); + } + } else { + __ GetCurrentThread(main_jni_conv->CurrentParamStackOffset(), + main_jni_conv->InterproceduralScratchRegister()); + if (is_64_bit_target) { + __ CallFromThread64(read_barrier64, main_jni_conv->InterproceduralScratchRegister()); + } else { + __ CallFromThread32(read_barrier32, main_jni_conv->InterproceduralScratchRegister()); + } + } + main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size)); // Reset. + } + // 6. Call into appropriate JniMethodStart passing Thread* so that transition out of Runnable // can occur. The result is the saved JNI local state that is restored by the exit call. We // abuse the JNI calling convention here, that is guaranteed to support passing 2 pointer diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index dbdcc96fc1..a871a82d95 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -176,7 +176,7 @@ TEST_F(OatTest, OatHeaderSizeCheck) { EXPECT_EQ(72U, sizeof(OatHeader)); EXPECT_EQ(4U, sizeof(OatMethodOffsets)); EXPECT_EQ(28U, sizeof(OatQuickMethodHeader)); - EXPECT_EQ(111 * GetInstructionSetPointerSize(kRuntimeISA), sizeof(QuickEntryPoints)); + EXPECT_EQ(112 * GetInstructionSetPointerSize(kRuntimeISA), sizeof(QuickEntryPoints)); } TEST_F(OatTest, OatHeaderIsValid) { |