diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/dex/mir_graph.cc | 8 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_common.cc | 4 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver_test.cc | 5 | ||||
| -rw-r--r-- | compiler/image_writer.cc | 48 | ||||
| -rw-r--r-- | compiler/llvm/gbc_expander.cc | 4 |
5 files changed, 56 insertions, 13 deletions
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc index db28f3a0e9..3ef1dbfac3 100644 --- a/compiler/dex/mir_graph.cc +++ b/compiler/dex/mir_graph.cc @@ -1072,19 +1072,21 @@ bool BasicBlock::RemoveMIRList(MIR* first_list_mir, MIR* last_list_mir) { } } - // Remove the BB information and also find the after_list + // Remove the BB information and also find the after_list. for (MIR* mir = first_list_mir; mir != last_list_mir; mir = mir->next) { mir->bb = NullBasicBlockId; } after_list = last_list_mir->next; - // If there is nothing before the list, after_list is the first_mir + // If there is nothing before the list, after_list is the first_mir. if (before_list == nullptr) { first_mir_insn = after_list; + } else { + before_list->next = after_list; } - // If there is nothing after the list, before_list is last_mir + // If there is nothing after the list, before_list is last_mir. if (after_list == nullptr) { last_mir_insn = before_list; } diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 4f2a87672a..03edf2ac39 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -603,6 +603,8 @@ void Mir2Lir::GenSput(MIR* mir, RegLocation rl_src, bool is_long_or_double, field_info.StorageIndex(), r_base)); FreeTemp(r_tmp); + // Ensure load of status and load of value don't re-order. + GenMemBarrier(kLoadLoad); } FreeTemp(r_method); } @@ -694,6 +696,8 @@ void Mir2Lir::GenSget(MIR* mir, RegLocation rl_dest, field_info.StorageIndex(), r_base)); FreeTemp(r_tmp); + // Ensure load of status and load of value don't re-order. + GenMemBarrier(kLoadLoad); } FreeTemp(r_method); } diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index 964dfeb5b1..ca956aac36 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -173,7 +173,10 @@ TEST_F(CompilerDriverTest, AbstractMethodErrorStub) { env_->ExceptionClear(); jclass jlame = env_->FindClass("java/lang/AbstractMethodError"); EXPECT_TRUE(env_->IsInstanceOf(exception, jlame)); - Thread::Current()->ClearException(); + { + ScopedObjectAccess soa(Thread::Current()); + Thread::Current()->ClearException(); + } } // TODO: need check-cast test (when stub complete & we can throw/catch diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index e37f943cca..ca1239f18d 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -650,34 +650,55 @@ void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) { copy->SetEntryPointFromInterpreter<kVerifyNone>(reinterpret_cast<EntryPointFromInterpreter*> (const_cast<byte*>(GetOatAddress(interpreter_to_interpreter_bridge_offset_)))); } else { - copy->SetEntryPointFromInterpreter<kVerifyNone>(reinterpret_cast<EntryPointFromInterpreter*> - (const_cast<byte*>(GetOatAddress(interpreter_to_compiled_code_bridge_offset_)))); // Use original code if it exists. Otherwise, set the code pointer to the resolution // trampoline. + + // Quick entrypoint: const byte* quick_code = GetOatAddress(orig->GetQuickOatCodeOffset()); + bool quick_is_interpreted = false; if (quick_code != nullptr && (!orig->IsStatic() || orig->IsConstructor() || orig->GetDeclaringClass()->IsInitialized())) { // We have code for a non-static or initialized method, just use the code. - copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(quick_code); } else if (quick_code == nullptr && orig->IsNative() && (!orig->IsStatic() || orig->GetDeclaringClass()->IsInitialized())) { // Non-static or initialized native method missing compiled code, use generic JNI version. - copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_generic_jni_trampoline_offset_)); + quick_code = GetOatAddress(quick_generic_jni_trampoline_offset_); } else if (quick_code == nullptr && !orig->IsNative()) { // We don't have code at all for a non-native method, use the interpreter. - copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_to_interpreter_bridge_offset_)); + quick_code = GetOatAddress(quick_to_interpreter_bridge_offset_); + quick_is_interpreted = true; } else { CHECK(!orig->GetDeclaringClass()->IsInitialized()); // We have code for a static method, but need to go through the resolution stub for class // initialization. - copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_resolution_trampoline_offset_)); + quick_code = GetOatAddress(quick_resolution_trampoline_offset_); } + copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(quick_code); + + // Portable entrypoint: const byte* portable_code = GetOatAddress(orig->GetPortableOatCodeOffset()); - if (portable_code != nullptr) { - copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(portable_code); + bool portable_is_interpreted = false; + if (portable_code != nullptr && + (!orig->IsStatic() || orig->IsConstructor() || orig->GetDeclaringClass()->IsInitialized())) { + // We have code for a non-static or initialized method, just use the code. + } else if (portable_code == nullptr && orig->IsNative() && + (!orig->IsStatic() || orig->GetDeclaringClass()->IsInitialized())) { + // Non-static or initialized native method missing compiled code, use generic JNI version. + // TODO: generic JNI support for LLVM. + portable_code = GetOatAddress(portable_resolution_trampoline_offset_); + } else if (portable_code == nullptr && !orig->IsNative()) { + // We don't have code at all for a non-native method, use the interpreter. + portable_code = GetOatAddress(portable_to_interpreter_bridge_offset_); + portable_is_interpreted = true; } else { - copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_resolution_trampoline_offset_)); + CHECK(!orig->GetDeclaringClass()->IsInitialized()); + // We have code for a static method, but need to go through the resolution stub for class + // initialization. + portable_code = GetOatAddress(portable_resolution_trampoline_offset_); } + copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(portable_code); + + // JNI entrypoint: if (orig->IsNative()) { // The native method's pointer is set to a stub to lookup via dlsym. // Note this is not the code_ pointer, that is handled above. @@ -688,6 +709,15 @@ void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) { const byte* native_gc_map = GetOatAddress(native_gc_map_offset); copy->SetNativeGcMap<kVerifyNone>(reinterpret_cast<const uint8_t*>(native_gc_map)); } + + // Interpreter entrypoint: + // Set the interpreter entrypoint depending on whether there is compiled code or not. + uint32_t interpreter_code = (quick_is_interpreted && portable_is_interpreted) + ? interpreter_to_interpreter_bridge_offset_ + : interpreter_to_compiled_code_bridge_offset_; + copy->SetEntryPointFromInterpreter<kVerifyNone>( + reinterpret_cast<EntryPointFromInterpreter*>( + const_cast<byte*>(GetOatAddress(interpreter_code)))); } } } diff --git a/compiler/llvm/gbc_expander.cc b/compiler/llvm/gbc_expander.cc index 25c9b20514..f8dca66de0 100644 --- a/compiler/llvm/gbc_expander.cc +++ b/compiler/llvm/gbc_expander.cc @@ -1868,6 +1868,10 @@ llvm::Value* GBCExpanderPass::EmitLoadStaticStorage(uint32_t dex_pc, phi->addIncoming(storage_object_addr, block_check_init); phi->addIncoming(loaded_storage_object_addr, block_after_load_static); + + // Ensure load of status and load of value don't re-order. + irb_.CreateMemoryBarrier(art::kLoadLoad); + return phi; } |