summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/mir_graph.cc8
-rw-r--r--compiler/dex/quick/gen_common.cc4
-rw-r--r--compiler/driver/compiler_driver_test.cc5
-rw-r--r--compiler/image_writer.cc48
-rw-r--r--compiler/llvm/gbc_expander.cc4
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;
}