summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/common_compiler_test.cc6
-rw-r--r--compiler/common_compiler_test.h2
-rw-r--r--compiler/debug/dwarf/debug_line_opcode_writer.h14
-rw-r--r--compiler/debug/dwarf/dwarf_test.cc4
-rw-r--r--compiler/debug/dwarf/dwarf_test.h2
-rw-r--r--compiler/debug/elf_debug_line_writer.h9
-rw-r--r--compiler/debug/elf_debug_writer.cc38
-rw-r--r--compiler/debug/elf_debug_writer.h6
-rw-r--r--compiler/debug/elf_gnu_debugdata_writer.h3
-rw-r--r--compiler/debug/method_debug_info.h1
-rw-r--r--compiler/dex/quick/dex_file_method_inliner.cc49
-rw-r--r--compiler/dex/quick/dex_file_method_inliner.h11
-rw-r--r--compiler/driver/compiler_options.h6
-rw-r--r--compiler/elf_builder.h5
-rw-r--r--compiler/elf_writer_quick.cc27
-rw-r--r--compiler/elf_writer_quick.h2
-rw-r--r--compiler/image_test.cc10
-rw-r--r--compiler/image_writer.cc36
-rw-r--r--compiler/image_writer.h2
-rw-r--r--compiler/jit/jit_compiler.cc3
-rw-r--r--compiler/jit/jit_compiler.h3
-rw-r--r--compiler/oat_test.cc1
-rw-r--r--compiler/oat_writer.cc4
-rw-r--r--compiler/optimizing/instruction_simplifier.cc16
-rw-r--r--compiler/optimizing/intrinsics.cc18
-rw-r--r--compiler/optimizing/intrinsics.h5
-rw-r--r--compiler/optimizing/intrinsics_arm.cc7
-rw-r--r--compiler/optimizing/intrinsics_arm64.cc7
-rw-r--r--compiler/optimizing/intrinsics_list.h8
-rw-r--r--compiler/optimizing/intrinsics_mips.cc9
-rw-r--r--compiler/optimizing/intrinsics_mips64.cc7
-rw-r--r--compiler/optimizing/intrinsics_x86.cc7
-rw-r--r--compiler/optimizing/intrinsics_x86_64.cc7
-rw-r--r--compiler/optimizing/nodes.h1
-rw-r--r--compiler/optimizing/optimizing_compiler.cc9
35 files changed, 293 insertions, 52 deletions
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 239bc590e9..6075cd6fbe 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -187,7 +187,9 @@ void CommonCompilerTest::SetUp() {
}
}
-void CommonCompilerTest::CreateCompilerDriver(Compiler::Kind kind, InstructionSet isa) {
+void CommonCompilerTest::CreateCompilerDriver(Compiler::Kind kind,
+ InstructionSet isa,
+ size_t number_of_threads) {
compiler_driver_.reset(new CompilerDriver(compiler_options_.get(),
verification_results_.get(),
method_inliner_map_.get(),
@@ -198,7 +200,7 @@ void CommonCompilerTest::CreateCompilerDriver(Compiler::Kind kind, InstructionSe
GetImageClasses(),
GetCompiledClasses(),
GetCompiledMethods(),
- /* thread_count */ 2,
+ number_of_threads,
/* dump_stats */ true,
/* dump_passes */ true,
timer_.get(),
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index 7e0fbabff8..9552143080 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -93,7 +93,7 @@ class CommonCompilerTest : public CommonRuntimeTest {
const char* method_name, const char* signature)
SHARED_REQUIRES(Locks::mutator_lock_);
- void CreateCompilerDriver(Compiler::Kind kind, InstructionSet isa);
+ void CreateCompilerDriver(Compiler::Kind kind, InstructionSet isa, size_t number_of_threads = 2U);
void ReserveImageSpace();
diff --git a/compiler/debug/dwarf/debug_line_opcode_writer.h b/compiler/debug/dwarf/debug_line_opcode_writer.h
index 58502a3f9c..b4a4d63f01 100644
--- a/compiler/debug/dwarf/debug_line_opcode_writer.h
+++ b/compiler/debug/dwarf/debug_line_opcode_writer.h
@@ -36,7 +36,7 @@ class DebugLineOpCodeWriter FINAL : private Writer<Vector> {
public:
static constexpr int kOpcodeBase = 13;
- static constexpr bool kDefaultIsStmt = true;
+ static constexpr bool kDefaultIsStmt = false;
static constexpr int kLineBase = -5;
static constexpr int kLineRange = 14;
@@ -81,8 +81,11 @@ class DebugLineOpCodeWriter FINAL : private Writer<Vector> {
this->PushUleb128(column);
}
- void NegateStmt() {
- this->PushUint8(DW_LNS_negate_stmt);
+ void SetIsStmt(bool is_stmt) {
+ if (is_stmt_ != is_stmt) {
+ this->PushUint8(DW_LNS_negate_stmt);
+ is_stmt_ = is_stmt;
+ }
}
void SetBasicBlock() {
@@ -112,6 +115,7 @@ class DebugLineOpCodeWriter FINAL : private Writer<Vector> {
current_address_ = 0;
current_file_ = 1;
current_line_ = 1;
+ is_stmt_ = kDefaultIsStmt;
}
// Uncoditionally set address using the long encoding.
@@ -227,7 +231,8 @@ class DebugLineOpCodeWriter FINAL : private Writer<Vector> {
code_factor_bits_(codeFactorBits),
current_address_(0),
current_file_(1),
- current_line_(1) {
+ current_line_(1),
+ is_stmt_(kDefaultIsStmt) {
}
private:
@@ -244,6 +249,7 @@ class DebugLineOpCodeWriter FINAL : private Writer<Vector> {
uint64_t current_address_;
int current_file_;
int current_line_;
+ bool is_stmt_;
std::vector<uintptr_t> patch_locations_;
DISALLOW_COPY_AND_ASSIGN(DebugLineOpCodeWriter);
diff --git a/compiler/debug/dwarf/dwarf_test.cc b/compiler/debug/dwarf/dwarf_test.cc
index e455d0d617..2ba3af5e10 100644
--- a/compiler/debug/dwarf/dwarf_test.cc
+++ b/compiler/debug/dwarf/dwarf_test.cc
@@ -217,7 +217,9 @@ TEST_F(DwarfTest, DebugLine) {
DW_CHECK_NEXT("Advance Line by 2 to 3");
opcodes.SetColumn(4);
DW_CHECK_NEXT("Set column to 4");
- opcodes.NegateStmt();
+ opcodes.SetIsStmt(true);
+ DW_CHECK_NEXT("Set is_stmt to 1");
+ opcodes.SetIsStmt(false);
DW_CHECK_NEXT("Set is_stmt to 0");
opcodes.SetBasicBlock();
DW_CHECK_NEXT("Set basic block");
diff --git a/compiler/debug/dwarf/dwarf_test.h b/compiler/debug/dwarf/dwarf_test.h
index 41bfe79c21..e2f0a65ab7 100644
--- a/compiler/debug/dwarf/dwarf_test.h
+++ b/compiler/debug/dwarf/dwarf_test.h
@@ -62,7 +62,7 @@ class DwarfTest : public CommonRuntimeTest {
InstructionSet isa = (sizeof(typename ElfTypes::Addr) == 8) ? kX86_64 : kX86;
ScratchFile file;
FileOutputStream output_stream(file.GetFile());
- ElfBuilder<ElfTypes> builder(isa, &output_stream);
+ ElfBuilder<ElfTypes> builder(isa, nullptr, &output_stream);
builder.Start();
if (!debug_info_data_.empty()) {
builder.WriteSection(".debug_info", &debug_info_data_);
diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h
index d3859ca752..11be4e9844 100644
--- a/compiler/debug/elf_debug_line_writer.h
+++ b/compiler/debug/elf_debug_line_writer.h
@@ -184,6 +184,10 @@ class ElfDebugLineWriter {
// Generate mapping opcodes from PC to Java lines.
if (file_index != 0) {
+ // If the method was not compiled as native-debuggable, we still generate all available
+ // lines, but we try to prevent the debugger from stepping and setting breakpoints since
+ // the information is too inaccurate for that (breakpoints would be set after the calls).
+ const bool default_is_stmt = mi->is_native_debuggable;
bool first = true;
for (SrcMapElem pc2dex : pc2dex_map) {
uint32_t pc = pc2dex.from_;
@@ -205,13 +209,14 @@ class ElfDebugLineWriter {
// Assume that any preceding code is prologue.
int first_line = dex2line_map.front().line_;
// Prologue is not a sensible place for a breakpoint.
- opcodes.NegateStmt();
+ opcodes.SetIsStmt(false);
opcodes.AddRow(method_address, first_line);
- opcodes.NegateStmt();
opcodes.SetPrologueEnd();
}
+ opcodes.SetIsStmt(default_is_stmt);
opcodes.AddRow(method_address + pc, line);
} else if (line != opcodes.CurrentLine()) {
+ opcodes.SetIsStmt(default_is_stmt);
opcodes.AddRow(method_address + pc, line);
}
}
diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc
index 01bd6797c9..79069d1aa2 100644
--- a/compiler/debug/elf_debug_writer.cc
+++ b/compiler/debug/elf_debug_writer.cc
@@ -91,24 +91,34 @@ static void WriteDebugSections(ElfBuilder<ElfTypes>* builder,
std::vector<uint8_t> MakeMiniDebugInfo(
InstructionSet isa,
+ const InstructionSetFeatures* features,
size_t rodata_size,
size_t text_size,
const ArrayRef<const MethodDebugInfo>& method_infos) {
if (Is64BitInstructionSet(isa)) {
- return MakeMiniDebugInfoInternal<ElfTypes64>(isa, rodata_size, text_size, method_infos);
+ return MakeMiniDebugInfoInternal<ElfTypes64>(isa,
+ features,
+ rodata_size,
+ text_size,
+ method_infos);
} else {
- return MakeMiniDebugInfoInternal<ElfTypes32>(isa, rodata_size, text_size, method_infos);
+ return MakeMiniDebugInfoInternal<ElfTypes32>(isa,
+ features,
+ rodata_size,
+ text_size,
+ method_infos);
}
}
template <typename ElfTypes>
static ArrayRef<const uint8_t> WriteDebugElfFileForMethodInternal(
+ const InstructionSet isa,
+ const InstructionSetFeatures* features,
const MethodDebugInfo& method_info) {
- const InstructionSet isa = method_info.compiled_method->GetInstructionSet();
std::vector<uint8_t> buffer;
buffer.reserve(KB);
VectorOutputStream out("Debug ELF file", &buffer);
- std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, features, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(false /* write_program_headers */);
WriteDebugInfo(builder.get(),
@@ -124,23 +134,26 @@ static ArrayRef<const uint8_t> WriteDebugElfFileForMethodInternal(
return ArrayRef<const uint8_t>(result, buffer.size());
}
-ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const MethodDebugInfo& method_info) {
- const InstructionSet isa = method_info.compiled_method->GetInstructionSet();
+ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const InstructionSet isa,
+ const InstructionSetFeatures* features,
+ const MethodDebugInfo& method_info) {
if (Is64BitInstructionSet(isa)) {
- return WriteDebugElfFileForMethodInternal<ElfTypes64>(method_info);
+ return WriteDebugElfFileForMethodInternal<ElfTypes64>(isa, features, method_info);
} else {
- return WriteDebugElfFileForMethodInternal<ElfTypes32>(method_info);
+ return WriteDebugElfFileForMethodInternal<ElfTypes32>(isa, features, method_info);
}
}
template <typename ElfTypes>
static ArrayRef<const uint8_t> WriteDebugElfFileForClassesInternal(
- const InstructionSet isa, const ArrayRef<mirror::Class*>& types)
+ const InstructionSet isa,
+ const InstructionSetFeatures* features,
+ const ArrayRef<mirror::Class*>& types)
SHARED_REQUIRES(Locks::mutator_lock_) {
std::vector<uint8_t> buffer;
buffer.reserve(KB);
VectorOutputStream out("Debug ELF file", &buffer);
- std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, features, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(false /* write_program_headers */);
ElfDebugInfoWriter<ElfTypes> info_writer(builder.get());
@@ -159,11 +172,12 @@ static ArrayRef<const uint8_t> WriteDebugElfFileForClassesInternal(
}
ArrayRef<const uint8_t> WriteDebugElfFileForClasses(const InstructionSet isa,
+ const InstructionSetFeatures* features,
const ArrayRef<mirror::Class*>& types) {
if (Is64BitInstructionSet(isa)) {
- return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, types);
+ return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, features, types);
} else {
- return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, types);
+ return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, features, types);
}
}
diff --git a/compiler/debug/elf_debug_writer.h b/compiler/debug/elf_debug_writer.h
index 103b501489..d364521f1b 100644
--- a/compiler/debug/elf_debug_writer.h
+++ b/compiler/debug/elf_debug_writer.h
@@ -37,13 +37,17 @@ void WriteDebugInfo(ElfBuilder<ElfTypes>* builder,
bool write_oat_patches);
std::vector<uint8_t> MakeMiniDebugInfo(InstructionSet isa,
+ const InstructionSetFeatures* features,
size_t rodata_section_size,
size_t text_section_size,
const ArrayRef<const MethodDebugInfo>& method_infos);
-ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const MethodDebugInfo& method_info);
+ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const InstructionSet isa,
+ const InstructionSetFeatures* features,
+ const MethodDebugInfo& method_info);
ArrayRef<const uint8_t> WriteDebugElfFileForClasses(const InstructionSet isa,
+ const InstructionSetFeatures* features,
const ArrayRef<mirror::Class*>& types)
SHARED_REQUIRES(Locks::mutator_lock_);
diff --git a/compiler/debug/elf_gnu_debugdata_writer.h b/compiler/debug/elf_gnu_debugdata_writer.h
index 5c7d1c72a4..fb63d62572 100644
--- a/compiler/debug/elf_gnu_debugdata_writer.h
+++ b/compiler/debug/elf_gnu_debugdata_writer.h
@@ -79,13 +79,14 @@ static void XzCompress(const std::vector<uint8_t>* src, std::vector<uint8_t>* ds
template <typename ElfTypes>
static std::vector<uint8_t> MakeMiniDebugInfoInternal(
InstructionSet isa,
+ const InstructionSetFeatures* features,
size_t rodata_section_size,
size_t text_section_size,
const ArrayRef<const MethodDebugInfo>& method_infos) {
std::vector<uint8_t> buffer;
buffer.reserve(KB);
VectorOutputStream out("Mini-debug-info ELF file", &buffer);
- std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, features, &out));
builder->Start();
// Mirror .rodata and .text as NOBITS sections.
// It is needed to detected relocations after compression.
diff --git a/compiler/debug/method_debug_info.h b/compiler/debug/method_debug_info.h
index 6b3dd8c528..bb09f7e814 100644
--- a/compiler/debug/method_debug_info.h
+++ b/compiler/debug/method_debug_info.h
@@ -30,6 +30,7 @@ struct MethodDebugInfo {
uint32_t access_flags;
const DexFile::CodeItem* code_item;
bool deduped;
+ bool is_native_debuggable;
uintptr_t low_pc;
uintptr_t high_pc;
CompiledMethod* compiled_method;
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index ad4ddadd2f..8f5d3ae4bd 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -101,6 +101,14 @@ static constexpr bool kIntrinsicIsStatic[] = {
false, // kIntrinsicCas
false, // kIntrinsicUnsafeGet
false, // kIntrinsicUnsafePut
+ false, // kIntrinsicUnsafeGetAndAddInt,
+ false, // kIntrinsicUnsafeGetAndAddLong,
+ false, // kIntrinsicUnsafeGetAndSetInt,
+ false, // kIntrinsicUnsafeGetAndSetLong,
+ false, // kIntrinsicUnsafeGetAndSetObject,
+ false, // kIntrinsicUnsafeLoadFence,
+ false, // kIntrinsicUnsafeStoreFence,
+ false, // kIntrinsicUnsafeFullFence,
true, // kIntrinsicSystemArrayCopyCharArray
true, // kIntrinsicSystemArrayCopy
};
@@ -177,6 +185,14 @@ static_assert(kIntrinsicIsStatic[kIntrinsicPoke], "Poke must be static");
static_assert(!kIntrinsicIsStatic[kIntrinsicCas], "Cas must not be static");
static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGet], "UnsafeGet must not be static");
static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafePut], "UnsafePut must not be static");
+static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddInt], "UnsafeGetAndAddInt must not be static");
+static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddLong], "UnsafeGetAndAddLong must not be static");
+static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetInt], "UnsafeGetAndSetInt must not be static");
+static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetLong], "UnsafeGetAndSetLong must not be static");
+static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetObject], "UnsafeGetAndSetObject must not be static");
+static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeLoadFence], "UnsafeLoadFence must not be static");
+static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeStoreFence], "UnsafeStoreFence must not be static");
+static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeFullFence], "UnsafeFullFence must not be static");
static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopyCharArray],
"SystemArrayCopyCharArray must be static");
static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopy],
@@ -318,6 +334,14 @@ const char* const DexFileMethodInliner::kNameCacheNames[] = {
"putObject", // kNameCachePutObject
"putObjectVolatile", // kNameCachePutObjectVolatile
"putOrderedObject", // kNameCachePutOrderedObject
+ "getAndAddInt", // kNameCacheGetAndAddInt,
+ "getAndAddLong", // kNameCacheGetAndAddLong,
+ "getAndSetInt", // kNameCacheGetAndSetInt,
+ "getAndSetLong", // kNameCacheGetAndSetLong,
+ "getAndSetObject", // kNameCacheGetAndSetObject,
+ "loadFence", // kNameCacheLoadFence,
+ "storeFence", // kNameCacheStoreFence,
+ "fullFence", // kNameCacheFullFence,
"arraycopy", // kNameCacheArrayCopy
"bitCount", // kNameCacheBitCount
"compare", // kNameCacheCompare
@@ -404,10 +428,14 @@ const DexFileMethodInliner::ProtoDef DexFileMethodInliner::kProtoCacheDefs[] = {
kClassCacheJavaLangObject, kClassCacheJavaLangObject } },
// kProtoCacheObjectJ_I
{ kClassCacheInt, 2, { kClassCacheJavaLangObject, kClassCacheLong } },
+ // kProtoCacheObjectJI_I
+ { kClassCacheInt, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheInt } },
// kProtoCacheObjectJI_V
{ kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheInt } },
// kProtoCacheObjectJ_J
{ kClassCacheLong, 2, { kClassCacheJavaLangObject, kClassCacheLong } },
+ // kProtoCacheObjectJJ_J
+ { kClassCacheLong, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheLong } },
// kProtoCacheObjectJJ_V
{ kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheLong } },
// kProtoCacheObjectJ_Object
@@ -415,6 +443,9 @@ const DexFileMethodInliner::ProtoDef DexFileMethodInliner::kProtoCacheDefs[] = {
// kProtoCacheObjectJObject_V
{ kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong,
kClassCacheJavaLangObject } },
+ // kProtoCacheObjectJObject_Object
+ { kClassCacheJavaLangObject, 3, { kClassCacheJavaLangObject, kClassCacheLong,
+ kClassCacheJavaLangObject } },
// kProtoCacheCharArrayICharArrayII_V
{ kClassCacheVoid, 5, {kClassCacheJavaLangCharArray, kClassCacheInt,
kClassCacheJavaLangCharArray, kClassCacheInt, kClassCacheInt} },
@@ -609,6 +640,16 @@ const DexFileMethodInliner::IntrinsicDef DexFileMethodInliner::kIntrinsicMethods
UNSAFE_GET_PUT(Object, Object, kIntrinsicFlagIsObject),
#undef UNSAFE_GET_PUT
+ // 1.8
+ INTRINSIC(SunMiscUnsafe, GetAndAddInt, ObjectJI_I, kIntrinsicUnsafeGetAndAddInt, 0),
+ INTRINSIC(SunMiscUnsafe, GetAndAddLong, ObjectJJ_J, kIntrinsicUnsafeGetAndAddLong, 0),
+ INTRINSIC(SunMiscUnsafe, GetAndSetInt, ObjectJI_I, kIntrinsicUnsafeGetAndSetInt, 0),
+ INTRINSIC(SunMiscUnsafe, GetAndSetLong, ObjectJJ_J, kIntrinsicUnsafeGetAndSetLong, 0),
+ INTRINSIC(SunMiscUnsafe, GetAndSetObject, ObjectJObject_Object, kIntrinsicUnsafeGetAndSetObject, 0),
+ INTRINSIC(SunMiscUnsafe, LoadFence, _V, kIntrinsicUnsafeLoadFence, 0),
+ INTRINSIC(SunMiscUnsafe, StoreFence, _V, kIntrinsicUnsafeStoreFence, 0),
+ INTRINSIC(SunMiscUnsafe, FullFence, _V, kIntrinsicUnsafeFullFence, 0),
+
INTRINSIC(JavaLangSystem, ArrayCopy, CharArrayICharArrayII_V , kIntrinsicSystemArrayCopyCharArray,
0),
INTRINSIC(JavaLangSystem, ArrayCopy, ObjectIObjectII_V , kIntrinsicSystemArrayCopy,
@@ -815,6 +856,14 @@ bool DexFileMethodInliner::GenIntrinsic(Mir2Lir* backend, CallInfo* info) {
case kIntrinsicRotateRight:
case kIntrinsicRotateLeft:
case kIntrinsicSignum:
+ case kIntrinsicUnsafeGetAndAddInt:
+ case kIntrinsicUnsafeGetAndAddLong:
+ case kIntrinsicUnsafeGetAndSetInt:
+ case kIntrinsicUnsafeGetAndSetLong:
+ case kIntrinsicUnsafeGetAndSetObject:
+ case kIntrinsicUnsafeLoadFence:
+ case kIntrinsicUnsafeStoreFence:
+ case kIntrinsicUnsafeFullFence:
case kIntrinsicSystemArrayCopy:
return false; // not implemented in quick.
default:
diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h
index b465db2c54..34b56cd494 100644
--- a/compiler/dex/quick/dex_file_method_inliner.h
+++ b/compiler/dex/quick/dex_file_method_inliner.h
@@ -227,6 +227,14 @@ class DexFileMethodInliner {
kNameCachePutObject,
kNameCachePutObjectVolatile,
kNameCachePutOrderedObject,
+ kNameCacheGetAndAddInt,
+ kNameCacheGetAndAddLong,
+ kNameCacheGetAndSetInt,
+ kNameCacheGetAndSetLong,
+ kNameCacheGetAndSetObject,
+ kNameCacheLoadFence,
+ kNameCacheStoreFence,
+ kNameCacheFullFence,
kNameCacheArrayCopy,
kNameCacheBitCount,
kNameCacheCompare,
@@ -282,11 +290,14 @@ class DexFileMethodInliner {
kProtoCacheObjectJJJ_Z,
kProtoCacheObjectJObjectObject_Z,
kProtoCacheObjectJ_I,
+ kProtoCacheObjectJI_I,
kProtoCacheObjectJI_V,
kProtoCacheObjectJ_J,
+ kProtoCacheObjectJJ_J,
kProtoCacheObjectJJ_V,
kProtoCacheObjectJ_Object,
kProtoCacheObjectJObject_V,
+ kProtoCacheObjectJObject_Object,
kProtoCacheCharArrayICharArrayII_V,
kProtoCacheObjectIObjectII_V,
kProtoCacheIICharArrayI_V,
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index a220959288..4db82a638d 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -159,10 +159,16 @@ class CompilerOptions FINAL {
size_t GetInlineDepthLimit() const {
return inline_depth_limit_;
}
+ void SetInlineDepthLimit(size_t limit) {
+ inline_depth_limit_ = limit;
+ }
size_t GetInlineMaxCodeUnits() const {
return inline_max_code_units_;
}
+ void SetInlineMaxCodeUnits(size_t units) {
+ inline_max_code_units_ = units;
+ }
double GetTopKProfileThreshold() const {
return top_k_profile_threshold_;
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index f7da609e5d..943e2a897d 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -20,6 +20,7 @@
#include <vector>
#include "arch/instruction_set.h"
+#include "arch/mips/instruction_set_features_mips.h"
#include "base/bit_utils.h"
#include "base/casts.h"
#include "base/unix_file/fd_file.h"
@@ -392,8 +393,9 @@ class ElfBuilder FINAL {
}
};
- ElfBuilder(InstructionSet isa, OutputStream* output)
+ ElfBuilder(InstructionSet isa, const InstructionSetFeatures* features, OutputStream* output)
: isa_(isa),
+ features_(features),
stream_(output),
rodata_(this, ".rodata", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kPageSize, 0),
text_(this, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, nullptr, 0, kPageSize, 0),
@@ -818,6 +820,7 @@ class ElfBuilder FINAL {
}
InstructionSet isa_;
+ const InstructionSetFeatures* features_;
ErrorDelayingOutputStream stream_;
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 19346ecc2b..e35662dfca 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -51,10 +51,12 @@ constexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_DEBUG_FRAME_FORMAT;
class DebugInfoTask : public Task {
public:
DebugInfoTask(InstructionSet isa,
+ const InstructionSetFeatures* features,
size_t rodata_section_size,
size_t text_section_size,
const ArrayRef<const debug::MethodDebugInfo>& method_infos)
: isa_(isa),
+ instruction_set_features_(features),
rodata_section_size_(rodata_section_size),
text_section_size_(text_section_size),
method_infos_(method_infos) {
@@ -62,6 +64,7 @@ class DebugInfoTask : public Task {
void Run(Thread*) {
result_ = debug::MakeMiniDebugInfo(isa_,
+ instruction_set_features_,
rodata_section_size_,
text_section_size_,
method_infos_);
@@ -73,6 +76,7 @@ class DebugInfoTask : public Task {
private:
InstructionSet isa_;
+ const InstructionSetFeatures* instruction_set_features_;
size_t rodata_section_size_;
size_t text_section_size_;
const ArrayRef<const debug::MethodDebugInfo>& method_infos_;
@@ -83,6 +87,7 @@ template <typename ElfTypes>
class ElfWriterQuick FINAL : public ElfWriter {
public:
ElfWriterQuick(InstructionSet instruction_set,
+ const InstructionSetFeatures* features,
const CompilerOptions* compiler_options,
File* elf_file);
~ElfWriterQuick();
@@ -107,6 +112,7 @@ class ElfWriterQuick FINAL : public ElfWriter {
std::vector<uint8_t>* buffer);
private:
+ const InstructionSetFeatures* instruction_set_features_;
const CompilerOptions* const compiler_options_;
File* const elf_file_;
size_t rodata_size_;
@@ -121,27 +127,36 @@ class ElfWriterQuick FINAL : public ElfWriter {
};
std::unique_ptr<ElfWriter> CreateElfWriterQuick(InstructionSet instruction_set,
+ const InstructionSetFeatures* features,
const CompilerOptions* compiler_options,
File* elf_file) {
if (Is64BitInstructionSet(instruction_set)) {
- return MakeUnique<ElfWriterQuick<ElfTypes64>>(instruction_set, compiler_options, elf_file);
+ return MakeUnique<ElfWriterQuick<ElfTypes64>>(instruction_set,
+ features,
+ compiler_options,
+ elf_file);
} else {
- return MakeUnique<ElfWriterQuick<ElfTypes32>>(instruction_set, compiler_options, elf_file);
+ return MakeUnique<ElfWriterQuick<ElfTypes32>>(instruction_set,
+ features,
+ compiler_options,
+ elf_file);
}
}
template <typename ElfTypes>
ElfWriterQuick<ElfTypes>::ElfWriterQuick(InstructionSet instruction_set,
+ const InstructionSetFeatures* features,
const CompilerOptions* compiler_options,
File* elf_file)
: ElfWriter(),
+ instruction_set_features_(features),
compiler_options_(compiler_options),
elf_file_(elf_file),
rodata_size_(0u),
text_size_(0u),
bss_size_(0u),
output_stream_(MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file))),
- builder_(new ElfBuilder<ElfTypes>(instruction_set, output_stream_.get())) {}
+ builder_(new ElfBuilder<ElfTypes>(instruction_set, features, output_stream_.get())) {}
template <typename ElfTypes>
ElfWriterQuick<ElfTypes>::~ElfWriterQuick() {}
@@ -205,7 +220,11 @@ void ElfWriterQuick<ElfTypes>::PrepareDebugInfo(
// Prepare the mini-debug-info in background while we do other I/O.
Thread* self = Thread::Current();
debug_info_task_ = std::unique_ptr<DebugInfoTask>(
- new DebugInfoTask(builder_->GetIsa(), rodata_size_, text_size_, method_infos));
+ new DebugInfoTask(builder_->GetIsa(),
+ instruction_set_features_,
+ rodata_size_,
+ text_size_,
+ method_infos));
debug_info_thread_pool_ = std::unique_ptr<ThreadPool>(
new ThreadPool("Mini-debug-info writer", 1));
debug_info_thread_pool_->AddTask(self, debug_info_task_.get());
diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h
index 347d372fe2..3d5dd39a66 100644
--- a/compiler/elf_writer_quick.h
+++ b/compiler/elf_writer_quick.h
@@ -26,8 +26,10 @@
namespace art {
class CompilerOptions;
+class InstructionSetFeatures;
std::unique_ptr<ElfWriter> CreateElfWriterQuick(InstructionSet instruction_set,
+ const InstructionSetFeatures* features,
const CompilerOptions* compiler_options,
File* elf_file);
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 5763cec43f..91579e9daf 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -24,6 +24,7 @@
#include "class_linker-inl.h"
#include "common_compiler_test.h"
#include "debug/method_debug_info.h"
+#include "driver/compiler_options.h"
#include "elf_writer.h"
#include "elf_writer_quick.h"
#include "gc/space/image_space.h"
@@ -48,8 +49,12 @@ class ImageTest : public CommonCompilerTest {
};
void ImageTest::TestWriteRead(ImageHeader::StorageMode storage_mode) {
- // TODO: Test does not currently work with optimizing.
- CreateCompilerDriver(Compiler::kQuick, kRuntimeISA);
+ CreateCompilerDriver(Compiler::kOptimizing, kRuntimeISA, kIsTargetBuild ? 2U : 16U);
+
+ // Set inline filter values.
+ compiler_options_->SetInlineDepthLimit(CompilerOptions::kDefaultInlineDepthLimit);
+ compiler_options_->SetInlineMaxCodeUnits(CompilerOptions::kDefaultInlineMaxCodeUnits);
+
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
// Enable write for dex2dex.
for (const DexFile* dex_file : class_linker->GetBootClassPath()) {
@@ -99,6 +104,7 @@ void ImageTest::TestWriteRead(ImageHeader::StorageMode storage_mode) {
const std::vector<const DexFile*>& dex_files = class_linker->GetBootClassPath();
std::unique_ptr<ElfWriter> elf_writer = CreateElfWriterQuick(
compiler_driver_->GetInstructionSet(),
+ compiler_driver_->GetInstructionSetFeatures(),
&compiler_driver_->GetCompilerOptions(),
oat_file.GetFile());
elf_writer->Start();
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 871435b85f..b1b971f6ba 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -266,17 +266,9 @@ bool ImageWriter::Write(int image_fd,
<< PrettyDuration(NanoTime() - compress_start_time);
}
- // Write header first, as uncompressed.
- image_header->data_size_ = data_size;
- if (!image_file->WriteFully(image_info.image_->Begin(), sizeof(ImageHeader))) {
- PLOG(ERROR) << "Failed to write image file header " << image_filename;
- image_file->Erase();
- return false;
- }
-
// Write out the image + fields + methods.
const bool is_compressed = compressed_data != nullptr;
- if (!image_file->WriteFully(image_data_to_write, data_size)) {
+ if (!image_file->PwriteFully(image_data_to_write, data_size, sizeof(ImageHeader))) {
PLOG(ERROR) << "Failed to write image file data " << image_filename;
image_file->Erase();
return false;
@@ -291,13 +283,33 @@ bool ImageWriter::Write(int image_fd,
if (!is_compressed) {
CHECK_EQ(bitmap_position_in_file, bitmap_section.Offset());
}
- if (!image_file->Write(reinterpret_cast<char*>(image_info.image_bitmap_->Begin()),
- bitmap_section.Size(),
- bitmap_position_in_file)) {
+ if (!image_file->PwriteFully(reinterpret_cast<char*>(image_info.image_bitmap_->Begin()),
+ bitmap_section.Size(),
+ bitmap_position_in_file)) {
PLOG(ERROR) << "Failed to write image file " << image_filename;
image_file->Erase();
return false;
}
+
+ int err = image_file->Flush();
+ if (err < 0) {
+ PLOG(ERROR) << "Failed to flush image file " << image_filename << " with result " << err;
+ image_file->Erase();
+ return false;
+ }
+
+ // Write header last in case the compiler gets killed in the middle of image writing.
+ // We do not want to have a corrupted image with a valid header.
+ // The header is uncompressed since it contains whether the image is compressed or not.
+ image_header->data_size_ = data_size;
+ if (!image_file->PwriteFully(reinterpret_cast<char*>(image_info.image_->Begin()),
+ sizeof(ImageHeader),
+ 0)) {
+ PLOG(ERROR) << "Failed to write image file header " << image_filename;
+ image_file->Erase();
+ return false;
+ }
+
CHECK_EQ(bitmap_position_in_file + bitmap_section.Size(),
static_cast<size_t>(image_file->GetLength()));
if (image_file->FlushCloseOrErase() != 0) {
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index dba9dd71fc..f204b28380 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -443,7 +443,7 @@ class ImageWriter FINAL {
static Bin BinTypeForNativeRelocationType(NativeObjectRelocationType type);
- uintptr_t NativeOffsetInImage(void* obj);
+ uintptr_t NativeOffsetInImage(void* obj) SHARED_REQUIRES(Locks::mutator_lock_);
// Location of where the object will be when the image is loaded at runtime.
template <typename T>
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index eeb25763a7..cda2e274ce 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -69,7 +69,8 @@ extern "C" void jit_types_loaded(void* handle, mirror::Class** types, size_t cou
DCHECK(jit_compiler != nullptr);
if (jit_compiler->GetCompilerOptions()->GetGenerateDebugInfo()) {
const ArrayRef<mirror::Class*> types_array(types, count);
- ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForClasses(kRuntimeISA, types_array);
+ ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForClasses(
+ kRuntimeISA, jit_compiler->GetCompilerDriver()->GetInstructionSetFeatures(), types_array);
CreateJITCodeEntry(std::unique_ptr<const uint8_t[]>(elf_file.data()), elf_file.size());
}
}
diff --git a/compiler/jit/jit_compiler.h b/compiler/jit/jit_compiler.h
index bc134fe27b..533dccf216 100644
--- a/compiler/jit/jit_compiler.h
+++ b/compiler/jit/jit_compiler.h
@@ -42,6 +42,9 @@ class JitCompiler {
CompilerOptions* GetCompilerOptions() const {
return compiler_options_.get();
}
+ CompilerDriver* GetCompilerDriver() const {
+ return compiler_driver_.get();
+ }
private:
std::unique_ptr<CompilerOptions> compiler_options_;
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 14fd1054c3..d22044aca3 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -176,6 +176,7 @@ class OatTest : public CommonCompilerTest {
bool verify) {
std::unique_ptr<ElfWriter> elf_writer = CreateElfWriterQuick(
compiler_driver_->GetInstructionSet(),
+ compiler_driver_->GetInstructionSetFeatures(),
&compiler_driver_->GetCompilerOptions(),
file);
elf_writer->Start();
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index c60b02a227..50f5aba061 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -806,7 +806,8 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor {
}
}
- if (writer_->compiler_driver_->GetCompilerOptions().GenerateAnyDebugInfo()) {
+ const CompilerOptions& compiler_options = writer_->compiler_driver_->GetCompilerOptions();
+ if (compiler_options.GenerateAnyDebugInfo()) {
// Record debug information for this function if we are doing that.
const uint32_t quick_code_start = quick_code_offset -
writer_->oat_header_->GetExecutableOffset() - thumb_offset;
@@ -817,6 +818,7 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor {
it.GetMethodAccessFlags(),
it.GetMethodCodeItem(),
deduped,
+ compiler_options.GetNativeDebuggable(),
quick_code_start,
quick_code_start + code_size,
compiled_method});
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index f8a9a94e62..b95ece5a31 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -94,6 +94,7 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
void SimplifyCompare(HInvoke* invoke, bool has_zero_op);
void SimplifyIsNaN(HInvoke* invoke);
void SimplifyFP2Int(HInvoke* invoke);
+ void SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind);
OptimizingCompilerStats* stats_;
bool simplification_occurred_ = false;
@@ -1594,6 +1595,12 @@ void InstructionSimplifierVisitor::SimplifyFP2Int(HInvoke* invoke) {
invoke->ReplaceWithExceptInReplacementAtIndex(select, 0); // false at index 0
}
+void InstructionSimplifierVisitor::SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind) {
+ uint32_t dex_pc = invoke->GetDexPc();
+ HMemoryBarrier* mem_barrier = new (GetGraph()->GetArena()) HMemoryBarrier(barrier_kind, dex_pc);
+ invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, mem_barrier);
+}
+
void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
switch (instruction->GetIntrinsic()) {
case Intrinsics::kStringEquals:
@@ -1626,6 +1633,15 @@ void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
case Intrinsics::kDoubleDoubleToLongBits:
SimplifyFP2Int(instruction);
break;
+ case Intrinsics::kUnsafeLoadFence:
+ SimplifyMemBarrier(instruction, MemBarrierKind::kLoadAny);
+ break;
+ case Intrinsics::kUnsafeStoreFence:
+ SimplifyMemBarrier(instruction, MemBarrierKind::kAnyStore);
+ break;
+ case Intrinsics::kUnsafeFullFence:
+ SimplifyMemBarrier(instruction, MemBarrierKind::kAnyAny);
+ break;
default:
break;
}
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index 3ed0278871..5d4c4e2950 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -472,6 +472,24 @@ static Intrinsics GetIntrinsic(InlineMethod method) {
break;
}
+ // 1.8.
+ case kIntrinsicUnsafeGetAndAddInt:
+ return Intrinsics::kUnsafeGetAndAddInt;
+ case kIntrinsicUnsafeGetAndAddLong:
+ return Intrinsics::kUnsafeGetAndAddLong;
+ case kIntrinsicUnsafeGetAndSetInt:
+ return Intrinsics::kUnsafeGetAndSetInt;
+ case kIntrinsicUnsafeGetAndSetLong:
+ return Intrinsics::kUnsafeGetAndSetLong;
+ case kIntrinsicUnsafeGetAndSetObject:
+ return Intrinsics::kUnsafeGetAndSetObject;
+ case kIntrinsicUnsafeLoadFence:
+ return Intrinsics::kUnsafeLoadFence;
+ case kIntrinsicUnsafeStoreFence:
+ return Intrinsics::kUnsafeStoreFence;
+ case kIntrinsicUnsafeFullFence:
+ return Intrinsics::kUnsafeFullFence;
+
// Virtual cases.
case kIntrinsicReferenceGetReferent:
diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h
index 0cec5ccfd3..3da82851a6 100644
--- a/compiler/optimizing/intrinsics.h
+++ b/compiler/optimizing/intrinsics.h
@@ -231,7 +231,10 @@ UNREACHABLE_INTRINSIC(Arch, LongRotateRight) \
UNREACHABLE_INTRINSIC(Arch, IntegerCompare) \
UNREACHABLE_INTRINSIC(Arch, LongCompare) \
UNREACHABLE_INTRINSIC(Arch, IntegerSignum) \
-UNREACHABLE_INTRINSIC(Arch, LongSignum)
+UNREACHABLE_INTRINSIC(Arch, LongSignum) \
+UNREACHABLE_INTRINSIC(Arch, UnsafeLoadFence) \
+UNREACHABLE_INTRINSIC(Arch, UnsafeStoreFence) \
+UNREACHABLE_INTRINSIC(Arch, UnsafeFullFence)
} // namespace art
diff --git a/compiler/optimizing/intrinsics_arm.cc b/compiler/optimizing/intrinsics_arm.cc
index 69c970852d..c7d9a0d2ce 100644
--- a/compiler/optimizing/intrinsics_arm.cc
+++ b/compiler/optimizing/intrinsics_arm.cc
@@ -2002,6 +2002,13 @@ UNIMPLEMENTED_INTRINSIC(ARM, LongHighestOneBit)
UNIMPLEMENTED_INTRINSIC(ARM, IntegerLowestOneBit)
UNIMPLEMENTED_INTRINSIC(ARM, LongLowestOneBit)
+// 1.8.
+UNIMPLEMENTED_INTRINSIC(ARM, UnsafeGetAndAddInt)
+UNIMPLEMENTED_INTRINSIC(ARM, UnsafeGetAndAddLong)
+UNIMPLEMENTED_INTRINSIC(ARM, UnsafeGetAndSetInt)
+UNIMPLEMENTED_INTRINSIC(ARM, UnsafeGetAndSetLong)
+UNIMPLEMENTED_INTRINSIC(ARM, UnsafeGetAndSetObject)
+
UNREACHABLE_INTRINSICS(ARM)
#undef __
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index 934b42762e..8a444412f3 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -1953,6 +1953,13 @@ UNIMPLEMENTED_INTRINSIC(ARM64, LongHighestOneBit)
UNIMPLEMENTED_INTRINSIC(ARM64, IntegerLowestOneBit)
UNIMPLEMENTED_INTRINSIC(ARM64, LongLowestOneBit)
+// 1.8.
+UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeGetAndAddInt)
+UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeGetAndAddLong)
+UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeGetAndSetInt)
+UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeGetAndSetLong)
+UNIMPLEMENTED_INTRINSIC(ARM64, UnsafeGetAndSetObject)
+
UNREACHABLE_INTRINSICS(ARM64)
#undef __
diff --git a/compiler/optimizing/intrinsics_list.h b/compiler/optimizing/intrinsics_list.h
index b8933e1684..dd9294d486 100644
--- a/compiler/optimizing/intrinsics_list.h
+++ b/compiler/optimizing/intrinsics_list.h
@@ -128,6 +128,14 @@
V(UnsafePutLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
V(UnsafePutLongOrdered, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
V(UnsafePutLongVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
+ V(UnsafeGetAndAddInt, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
+ V(UnsafeGetAndAddLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
+ V(UnsafeGetAndSetInt, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
+ V(UnsafeGetAndSetLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
+ V(UnsafeGetAndSetObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
+ V(UnsafeLoadFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
+ V(UnsafeStoreFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
+ V(UnsafeFullFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \
V(ReferenceGetReferent, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow)
#endif // ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc
index 710df0a822..e159701a46 100644
--- a/compiler/optimizing/intrinsics_mips.cc
+++ b/compiler/optimizing/intrinsics_mips.cc
@@ -1832,9 +1832,14 @@ UNIMPLEMENTED_INTRINSIC(MIPS, MathSinh)
UNIMPLEMENTED_INTRINSIC(MIPS, MathTan)
UNIMPLEMENTED_INTRINSIC(MIPS, MathTanh)
-UNREACHABLE_INTRINSICS(MIPS)
+// 1.8.
+UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeGetAndAddInt)
+UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeGetAndAddLong)
+UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeGetAndSetInt)
+UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeGetAndSetLong)
+UNIMPLEMENTED_INTRINSIC(MIPS, UnsafeGetAndSetObject)
-#undef UNIMPLEMENTED_INTRINSIC
+UNREACHABLE_INTRINSICS(MIPS)
#undef __
diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc
index 617844bb18..0dc602f1ef 100644
--- a/compiler/optimizing/intrinsics_mips64.cc
+++ b/compiler/optimizing/intrinsics_mips64.cc
@@ -1729,6 +1729,13 @@ UNIMPLEMENTED_INTRINSIC(MIPS64, LongHighestOneBit)
UNIMPLEMENTED_INTRINSIC(MIPS64, IntegerLowestOneBit)
UNIMPLEMENTED_INTRINSIC(MIPS64, LongLowestOneBit)
+// 1.8.
+UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeGetAndAddInt)
+UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeGetAndAddLong)
+UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeGetAndSetInt)
+UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeGetAndSetLong)
+UNIMPLEMENTED_INTRINSIC(MIPS64, UnsafeGetAndSetObject)
+
UNREACHABLE_INTRINSICS(MIPS64)
#undef __
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index 9a2dc4182d..4c802c0a1a 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -2637,6 +2637,13 @@ UNIMPLEMENTED_INTRINSIC(X86, LongHighestOneBit)
UNIMPLEMENTED_INTRINSIC(X86, IntegerLowestOneBit)
UNIMPLEMENTED_INTRINSIC(X86, LongLowestOneBit)
+// 1.8.
+UNIMPLEMENTED_INTRINSIC(X86, UnsafeGetAndAddInt)
+UNIMPLEMENTED_INTRINSIC(X86, UnsafeGetAndAddLong)
+UNIMPLEMENTED_INTRINSIC(X86, UnsafeGetAndSetInt)
+UNIMPLEMENTED_INTRINSIC(X86, UnsafeGetAndSetLong)
+UNIMPLEMENTED_INTRINSIC(X86, UnsafeGetAndSetObject)
+
UNREACHABLE_INTRINSICS(X86)
#undef __
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index 75204b4b49..41095cd485 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -2715,6 +2715,13 @@ UNIMPLEMENTED_INTRINSIC(X86_64, ReferenceGetReferent)
UNIMPLEMENTED_INTRINSIC(X86_64, FloatIsInfinite)
UNIMPLEMENTED_INTRINSIC(X86_64, DoubleIsInfinite)
+// 1.8.
+UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeGetAndAddInt)
+UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeGetAndAddLong)
+UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeGetAndSetInt)
+UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeGetAndSetLong)
+UNIMPLEMENTED_INTRINSIC(X86_64, UnsafeGetAndSetObject)
+
UNREACHABLE_INTRINSICS(X86_64)
#undef __
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index b684cc697f..ecb690ff62 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -26,6 +26,7 @@
#include "base/arena_object.h"
#include "base/stl_util.h"
#include "dex/compiler_enums.h"
+#include "dex_instruction-inl.h"
#include "entrypoints/quick/quick_entrypoints_enum.h"
#include "handle.h"
#include "handle_scope.h"
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index c1b4d2403d..42f22afd80 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -913,7 +913,8 @@ bool OptimizingCompiler::JitCompile(Thread* self,
return false;
}
- if (GetCompilerDriver()->GetCompilerOptions().GetGenerateDebugInfo()) {
+ const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
+ if (compiler_options.GetGenerateDebugInfo()) {
const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code);
const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode());
CompiledMethod compiled_method(
@@ -936,11 +937,15 @@ bool OptimizingCompiler::JitCompile(Thread* self,
access_flags,
code_item,
false, // deduped.
+ compiler_options.GetNativeDebuggable(),
code_address,
code_address + code_allocator.GetSize(),
&compiled_method
};
- ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForMethod(method_debug_info);
+ ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForMethod(
+ GetCompilerDriver()->GetInstructionSet(),
+ GetCompilerDriver()->GetInstructionSetFeatures(),
+ method_debug_info);
CreateJITCodeEntryForAddress(code_address,
std::unique_ptr<const uint8_t[]>(elf_file.data()),
elf_file.size());