summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-04-22 13:56:20 -0700
committerMathieu Chartier <mathieuc@google.com>2015-06-02 09:21:27 -0700
commit3d21bdf8894e780d349c481e5c9e29fe1556051c (patch)
tree61a5231f36c0dabd73457fec81df103462a05aff /compiler/dex/quick
parent71f0a8a123fa27bdc857a98afebbaf0ed09dac15 (diff)
downloadandroid_art-3d21bdf8894e780d349c481e5c9e29fe1556051c.tar.gz
android_art-3d21bdf8894e780d349c481e5c9e29fe1556051c.tar.bz2
android_art-3d21bdf8894e780d349c481e5c9e29fe1556051c.zip
Move mirror::ArtMethod to native
Optimizing + quick tests are passing, devices boot. TODO: Test and fix bugs in mips64. Saves 16 bytes per most ArtMethod, 7.5MB reduction in system PSS. Some of the savings are from removal of virtual methods and direct methods object arrays. Bug: 19264997 (cherry picked from commit e401d146407d61eeb99f8d6176b2ac13c4df1e33) Change-Id: I622469a0cfa0e7082a2119f3d6a9491eb61e3f3d Fix some ArtMethod related bugs Added root visiting for runtime methods, not currently required since the GcRoots in these methods are null. Added missing GetInterfaceMethodIfProxy in GetMethodLine, fixes --trace run-tests 005, 044. Fixed optimizing compiler bug where we used a normal stack location instead of double on ARM64, this fixes the debuggable tests. TODO: Fix JDWP tests. Bug: 19264997 Change-Id: I7c55f69c61d1b45351fd0dc7185ffe5efad82bd3 ART: Fix casts for 64-bit pointers on 32-bit compiler. Bug: 19264997 Change-Id: Ief45cdd4bae5a43fc8bfdfa7cf744e2c57529457 Fix JDWP tests after ArtMethod change Fixes Throwable::GetStackDepth for exception event detection after internal stack trace representation change. Adds missing ArtMethod::GetInterfaceMethodIfProxy call in case of proxy method. Bug: 19264997 Change-Id: I363e293796848c3ec491c963813f62d868da44d2 Fix accidental IMT and root marking regression Was always using the conflict trampoline. Also included fix for regression in GC time caused by extra roots. Most of the regression was IMT. Fixed bug in DumpGcPerformanceInfo where we would get SIGABRT due to detached thread. EvaluateAndApplyChanges: From ~2500 -> ~1980 GC time: 8.2s -> 7.2s due to 1s less of MarkConcurrentRoots Bug: 19264997 Change-Id: I4333e80a8268c2ed1284f87f25b9f113d4f2c7e0 Fix bogus image test assert Previously we were comparing the size of the non moving space to size of the image file. Now we properly compare the size of the image space against the size of the image file. Bug: 19264997 Change-Id: I7359f1f73ae3df60c5147245935a24431c04808a [MIPS64] Fix art_quick_invoke_stub argument offsets. ArtMethod reference's size got bigger, so we need to move other args and leave enough space for ArtMethod* and 'this' pointer. This fixes mips64 boot. Bug: 19264997 Change-Id: I47198d5f39a4caab30b3b77479d5eedaad5006ab
Diffstat (limited to 'compiler/dex/quick')
-rw-r--r--compiler/dex/quick/arm/call_arm.cc10
-rw-r--r--compiler/dex/quick/arm/codegen_arm.h3
-rw-r--r--compiler/dex/quick/arm/int_arm.cc4
-rw-r--r--compiler/dex/quick/arm64/arm64_lir.h4
-rw-r--r--compiler/dex/quick/arm64/call_arm64.cc25
-rw-r--r--compiler/dex/quick/arm64/codegen_arm64.h3
-rw-r--r--compiler/dex/quick/arm64/int_arm64.cc9
-rw-r--r--compiler/dex/quick/arm64/target_arm64.cc9
-rw-r--r--compiler/dex/quick/codegen_util.cc7
-rw-r--r--compiler/dex/quick/gen_common.cc39
-rwxr-xr-xcompiler/dex/quick/gen_invoke.cc33
-rw-r--r--compiler/dex/quick/gen_loadstore.cc20
-rw-r--r--compiler/dex/quick/mips/call_mips.cc23
-rw-r--r--compiler/dex/quick/mir_to_lir.cc4
-rw-r--r--compiler/dex/quick/mir_to_lir.h14
-rw-r--r--compiler/dex/quick/quick_cfi_test.cc3
-rw-r--r--compiler/dex/quick/quick_cfi_test_expected.inc50
-rw-r--r--compiler/dex/quick/quick_compiler.cc4
-rw-r--r--compiler/dex/quick/quick_compiler.h2
-rw-r--r--compiler/dex/quick/x86/call_x86.cc21
-rw-r--r--compiler/dex/quick/x86/codegen_x86.h3
-rwxr-xr-xcompiler/dex/quick/x86/int_x86.cc20
-rwxr-xr-xcompiler/dex/quick/x86/target_x86.cc7
-rw-r--r--compiler/dex/quick/x86/x86_lir.h4
24 files changed, 177 insertions, 144 deletions
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc
index 822ea2106f..981ab2c1ee 100644
--- a/compiler/dex/quick/arm/call_arm.cc
+++ b/compiler/dex/quick/arm/call_arm.cc
@@ -19,6 +19,7 @@
#include "codegen_arm.h"
#include "arm_lir.h"
+#include "art_method.h"
#include "base/bit_utils.h"
#include "base/logging.h"
#include "dex/mir_graph.h"
@@ -27,7 +28,6 @@
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
#include "gc/accounting/card_table.h"
-#include "mirror/art_method.h"
#include "mirror/object_array-inl.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "utils/dex_cache_arrays_layout-inl.h"
@@ -637,7 +637,7 @@ int ArmMir2Lir::ArmNextSDCallInsn(CompilationUnit* cu, CallInfo* info,
if (direct_code == 0) {
// kInvokeTgt := arg0_ref->entrypoint
cg->LoadWordDisp(arg0_ref,
- mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
+ ArtMethod::EntryPointFromQuickCompiledCodeOffset(
kArmPointerSize).Int32Value(), cg->TargetPtrReg(kInvokeTgt));
}
break;
@@ -678,7 +678,7 @@ int ArmMir2Lir::ArmNextSDCallInsn(CompilationUnit* cu, CallInfo* info,
case 1: // Get method->dex_cache_resolved_methods_
if (!use_pc_rel) {
cg->LoadRefDisp(arg0_ref,
- mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(),
+ ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(),
arg0_ref,
kNotVolatile);
}
@@ -708,14 +708,14 @@ int ArmMir2Lir::ArmNextSDCallInsn(CompilationUnit* cu, CallInfo* info,
kNotVolatile);
} else {
size_t offset = cg->dex_cache_arrays_layout_.MethodOffset(target_method.dex_method_index);
- cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref);
+ cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref, false);
}
break;
case 3: // Grab the code from the method*
if (direct_code == 0) {
// kInvokeTgt := arg0_ref->entrypoint
cg->LoadWordDisp(arg0_ref,
- mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
+ ArtMethod::EntryPointFromQuickCompiledCodeOffset(
kArmPointerSize).Int32Value(), cg->TargetPtrReg(kInvokeTgt));
}
break;
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h
index 83b27df939..b94e707354 100644
--- a/compiler/dex/quick/arm/codegen_arm.h
+++ b/compiler/dex/quick/arm/codegen_arm.h
@@ -83,7 +83,8 @@ class ArmMir2Lir FINAL : public Mir2Lir {
void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE;
bool CanUseOpPcRelDexCacheArrayLoad() const OVERRIDE;
- void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest) OVERRIDE;
+ void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest,
+ bool wide) OVERRIDE;
// Required for target - register utilities.
RegStorage TargetReg(SpecialTargetRegister reg) OVERRIDE;
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 7de8e55e56..6d30e72f86 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -1107,7 +1107,9 @@ void ArmMir2Lir::OpPcRelDexCacheArrayAddr(const DexFile* dex_file, int offset, R
dex_cache_access_insns_.push_back(movt);
}
-void ArmMir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest) {
+void ArmMir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest,
+ bool wide) {
+ DCHECK(!wide) << "Unsupported";
if (dex_cache_arrays_base_reg_.Valid()) {
LoadRefDisp(dex_cache_arrays_base_reg_, offset - dex_cache_arrays_min_offset_,
r_dest, kNotVolatile);
diff --git a/compiler/dex/quick/arm64/arm64_lir.h b/compiler/dex/quick/arm64/arm64_lir.h
index 5bf77aae55..c530a8b23a 100644
--- a/compiler/dex/quick/arm64/arm64_lir.h
+++ b/compiler/dex/quick/arm64/arm64_lir.h
@@ -71,7 +71,7 @@ namespace art {
* | IN[ins-1] | {Note: resides in caller's frame}
* | . |
* | IN[0] |
- * | caller's method (StackReference<ArtMethod>)| {This is a compressed (4-bytes) reference}
+ * | caller's method ArtMethod* | {Pointer sized reference}
* +============================================+ {Note: start of callee's frame}
* | spill region | {variable sized - will include lr if non-leaf}
* +--------------------------------------------+
@@ -90,7 +90,7 @@ namespace art {
* | OUT[outs-2] |
* | . |
* | OUT[0] |
- * | current method (StackReference<ArtMethod>) | <<== sp w/ 16-byte alignment
+ * | current method ArtMethod* | <<== sp w/ 16-byte alignment
* +============================================+
*/
diff --git a/compiler/dex/quick/arm64/call_arm64.cc b/compiler/dex/quick/arm64/call_arm64.cc
index e49e40d868..83a6affe81 100644
--- a/compiler/dex/quick/arm64/call_arm64.cc
+++ b/compiler/dex/quick/arm64/call_arm64.cc
@@ -19,6 +19,7 @@
#include "codegen_arm64.h"
#include "arm64_lir.h"
+#include "art_method.h"
#include "base/logging.h"
#include "dex/mir_graph.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
@@ -27,7 +28,6 @@
#include "driver/compiler_options.h"
#include "gc/accounting/card_table.h"
#include "entrypoints/quick/quick_entrypoints.h"
-#include "mirror/art_method.h"
#include "mirror/object_array-inl.h"
#include "utils/dex_cache_arrays_layout-inl.h"
@@ -456,23 +456,22 @@ static bool Arm64UseRelativeCall(CompilationUnit* cu, const MethodReference& tar
*/
int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info,
int state, const MethodReference& target_method,
- uint32_t unused_idx,
+ uint32_t unused_idx ATTRIBUTE_UNUSED,
uintptr_t direct_code, uintptr_t direct_method,
InvokeType type) {
- UNUSED(info, unused_idx);
Arm64Mir2Lir* cg = static_cast<Arm64Mir2Lir*>(cu->cg.get());
if (info->string_init_offset != 0) {
RegStorage arg0_ref = cg->TargetReg(kArg0, kRef);
switch (state) {
case 0: { // Grab target method* from thread pointer
- cg->LoadRefDisp(rs_xSELF, info->string_init_offset, arg0_ref, kNotVolatile);
+ cg->LoadWordDisp(rs_xSELF, info->string_init_offset, arg0_ref);
break;
}
case 1: // Grab the code from the method*
if (direct_code == 0) {
// kInvokeTgt := arg0_ref->entrypoint
cg->LoadWordDisp(arg0_ref,
- mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
+ ArtMethod::EntryPointFromQuickCompiledCodeOffset(
kArm64PointerSize).Int32Value(), cg->TargetPtrReg(kInvokeTgt));
}
break;
@@ -500,7 +499,7 @@ int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info,
}
} else {
bool use_pc_rel = cg->CanUseOpPcRelDexCacheArrayLoad();
- RegStorage arg0_ref = cg->TargetReg(kArg0, kRef);
+ RegStorage arg0_ref = cg->TargetPtrReg(kArg0);
switch (state) {
case 0: // Get the current Method* [sets kArg0]
// TUNING: we can save a reg copy if Method* has been promoted.
@@ -513,7 +512,7 @@ int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info,
case 1: // Get method->dex_cache_resolved_methods_
if (!use_pc_rel) {
cg->LoadRefDisp(arg0_ref,
- mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(),
+ ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(),
arg0_ref,
kNotVolatile);
}
@@ -536,21 +535,19 @@ int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info,
case 2: // Grab target method*
CHECK_EQ(cu->dex_file, target_method.dex_file);
if (!use_pc_rel) {
- cg->LoadRefDisp(arg0_ref,
- mirror::ObjectArray<mirror::Object>::OffsetOfElement(
- target_method.dex_method_index).Int32Value(),
- arg0_ref,
- kNotVolatile);
+ cg->LoadWordDisp(arg0_ref,
+ mirror::Array::DataOffset(kArm64PointerSize).Uint32Value() +
+ target_method.dex_method_index * kArm64PointerSize, arg0_ref);
} else {
size_t offset = cg->dex_cache_arrays_layout_.MethodOffset(target_method.dex_method_index);
- cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref);
+ cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref, true);
}
break;
case 3: // Grab the code from the method*
if (direct_code == 0) {
// kInvokeTgt := arg0_ref->entrypoint
cg->LoadWordDisp(arg0_ref,
- mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
+ ArtMethod::EntryPointFromQuickCompiledCodeOffset(
kArm64PointerSize).Int32Value(), cg->TargetPtrReg(kInvokeTgt));
}
break;
diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h
index 8184f02287..ca2e012950 100644
--- a/compiler/dex/quick/arm64/codegen_arm64.h
+++ b/compiler/dex/quick/arm64/codegen_arm64.h
@@ -79,7 +79,8 @@ class Arm64Mir2Lir FINAL : public Mir2Lir {
void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE;
bool CanUseOpPcRelDexCacheArrayLoad() const OVERRIDE;
- void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest) OVERRIDE;
+ void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, bool wide)
+ OVERRIDE;
LIR* OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg,
int offset, int check_value, LIR* target, LIR** compare) OVERRIDE;
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc
index 08aa5d20d0..31cf6675af 100644
--- a/compiler/dex/quick/arm64/int_arm64.cc
+++ b/compiler/dex/quick/arm64/int_arm64.cc
@@ -947,14 +947,17 @@ bool Arm64Mir2Lir::CanUseOpPcRelDexCacheArrayLoad() const {
return dex_cache_arrays_layout_.Valid();
}
-void Arm64Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset,
- RegStorage r_dest) {
+void Arm64Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest,
+ bool wide) {
LIR* adrp = NewLIR2(kA64Adrp2xd, r_dest.GetReg(), 0);
adrp->operands[2] = WrapPointer(dex_file);
adrp->operands[3] = offset;
adrp->operands[4] = WrapPointer(adrp);
dex_cache_access_insns_.push_back(adrp);
- LIR* ldr = LoadBaseDisp(r_dest, 0, r_dest, kReference, kNotVolatile);
+ if (wide) {
+ DCHECK(r_dest.Is64Bit());
+ }
+ LIR* ldr = LoadBaseDisp(r_dest, 0, r_dest, wide ? k64 : kReference, kNotVolatile);
ldr->operands[4] = adrp->operands[4];
ldr->flags.fixup = kFixupLabel;
dex_cache_access_insns_.push_back(ldr);
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index fc32ecd955..d5de18d865 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -859,7 +859,8 @@ void Arm64Mir2Lir::InstallLiteralPools() {
// PC-relative references to dex cache arrays.
for (LIR* p : dex_cache_access_insns_) {
- DCHECK(p->opcode == kA64Adrp2xd || p->opcode == kA64Ldr3rXD);
+ auto non_wide = UNWIDE(p->opcode); // May be a wide load for ArtMethod*.
+ DCHECK(non_wide == kA64Adrp2xd || non_wide == kA64Ldr3rXD) << p->opcode << " " << non_wide;
const LIR* adrp = UnwrapPointer<LIR>(p->operands[4]);
DCHECK_EQ(adrp->opcode, kA64Adrp2xd);
const DexFile* dex_file = UnwrapPointer<DexFile>(adrp->operands[2]);
@@ -895,8 +896,7 @@ void Arm64Mir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir)
rl_src[0] = mir_graph_->GetSrc(mir, 0);
rl_src[1] = mir_graph_->GetSrc(mir, 1);
rl_src[2]= mir_graph_->GetSrc(mir, 2);
- GenMaddMsubInt(rl_dest, rl_src[0], rl_src[1], rl_src[2],
- (opcode == kMirOpMsubInt) ? true : false);
+ GenMaddMsubInt(rl_dest, rl_src[0], rl_src[1], rl_src[2], opcode == kMirOpMsubInt);
break;
case kMirOpMaddLong:
case kMirOpMsubLong:
@@ -904,8 +904,7 @@ void Arm64Mir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir)
rl_src[0] = mir_graph_->GetSrcWide(mir, 0);
rl_src[1] = mir_graph_->GetSrcWide(mir, 2);
rl_src[2] = mir_graph_->GetSrcWide(mir, 4);
- GenMaddMsubLong(rl_dest, rl_src[0], rl_src[1], rl_src[2],
- (opcode == kMirOpMsubLong) ? true : false);
+ GenMaddMsubLong(rl_dest, rl_src[0], rl_src[1], rl_src[2], opcode == kMirOpMsubLong);
break;
default:
LOG(FATAL) << "Unexpected opcode: " << static_cast<int>(opcode);
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 86bb69d01e..f4bf31fb8a 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -1298,8 +1298,8 @@ void Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType
// resolve these invokes to the same method, so we don't care which one we record here.
data_target->operands[2] = type;
}
- // Loads an ArtMethod pointer, which is a reference as it lives in the heap.
- OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target);
+ // Loads an ArtMethod pointer, which is not a reference.
+ OpPcRelLoad(TargetPtrReg(symbolic_reg), data_target);
DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target);
DCHECK_NE(cu_->instruction_set, kMips64) << reinterpret_cast<void*>(data_target);
}
@@ -1322,7 +1322,8 @@ bool Mir2Lir::CanUseOpPcRelDexCacheArrayLoad() const {
void Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file ATTRIBUTE_UNUSED,
int offset ATTRIBUTE_UNUSED,
- RegStorage r_dest ATTRIBUTE_UNUSED) {
+ RegStorage r_dest ATTRIBUTE_UNUSED,
+ bool wide ATTRIBUTE_UNUSED) {
LOG(FATAL) << "No generic implementation.";
UNREACHABLE();
}
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index 63f83f94cf..af108170e6 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -97,11 +97,11 @@ RegStorage Mir2Lir::GenGetOtherTypeForSgetSput(const MirSFieldLoweringInfo& fiel
LockTemp(r_base);
if (CanUseOpPcRelDexCacheArrayLoad()) {
uint32_t offset = dex_cache_arrays_layout_.TypeOffset(field_info.StorageIndex());
- OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, r_base);
+ OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, r_base, false);
} else {
// Using fixed register to sync with possible call to runtime support.
RegStorage r_method = LoadCurrMethodWithHint(r_base);
- LoadRefDisp(r_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), r_base,
+ LoadRefDisp(r_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), r_base,
kNotVolatile);
int32_t offset_of_field = ObjArray::OffsetOfElement(field_info.StorageIndex()).Int32Value();
LoadRefDisp(r_base, offset_of_field, r_base, kNotVolatile);
@@ -693,7 +693,7 @@ void Mir2Lir::GenSput(MIR* mir, RegLocation rl_src, OpSize size) {
// Fast path, static storage base is this method's class
r_base = AllocTempRef();
RegStorage r_method = LoadCurrMethodWithHint(r_base);
- LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), r_base,
+ LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), r_base,
kNotVolatile);
} else {
// Medium path, static storage base in a different class which requires checks that the other
@@ -771,7 +771,7 @@ void Mir2Lir::GenSget(MIR* mir, RegLocation rl_dest, OpSize size, Primitive::Typ
// Fast path, static storage base is this method's class
r_base = AllocTempRef();
RegStorage r_method = LoadCurrMethodWithHint(r_base);
- LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), r_base,
+ LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), r_base,
kNotVolatile);
} else {
// Medium path, static storage base in a different class which requires checks that the other
@@ -1031,10 +1031,10 @@ void Mir2Lir::GenConstClass(uint32_t type_idx, RegLocation rl_dest) {
// We don't need access checks, load type from dex cache
if (CanUseOpPcRelDexCacheArrayLoad()) {
size_t offset = dex_cache_arrays_layout_.TypeOffset(type_idx);
- OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, rl_result.reg);
+ OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, rl_result.reg, false);
} else {
int32_t dex_cache_offset =
- mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value();
+ ArtMethod::DexCacheResolvedTypesOffset().Int32Value();
RegStorage res_reg = AllocTempRef();
RegStorage r_method = LoadCurrMethodWithHint(res_reg);
LoadRefDisp(r_method, dex_cache_offset, res_reg, kNotVolatile);
@@ -1066,13 +1066,12 @@ void Mir2Lir::GenConstString(uint32_t string_idx, RegLocation rl_dest) {
RegStorage ret0 = TargetReg(kRet0, kRef);
if (CanUseOpPcRelDexCacheArrayLoad()) {
size_t offset = dex_cache_arrays_layout_.StringOffset(string_idx);
- OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, ret0);
+ OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, ret0, false);
} else {
// Method to declaring class.
RegStorage arg0 = TargetReg(kArg0, kRef);
RegStorage r_method = LoadCurrMethodWithHint(arg0);
- LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
- arg0, kNotVolatile);
+ LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), arg0, kNotVolatile);
// Declaring class to dex cache strings.
LoadRefDisp(arg0, mirror::Class::DexCacheStringsOffset().Int32Value(), arg0, kNotVolatile);
@@ -1086,11 +1085,11 @@ void Mir2Lir::GenConstString(uint32_t string_idx, RegLocation rl_dest) {
RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true);
if (CanUseOpPcRelDexCacheArrayLoad()) {
size_t offset = dex_cache_arrays_layout_.StringOffset(string_idx);
- OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, rl_result.reg);
+ OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, rl_result.reg, false);
} else {
RegLocation rl_method = LoadCurrMethod();
RegStorage res_reg = AllocTempRef();
- LoadRefDisp(rl_method.reg, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), res_reg,
+ LoadRefDisp(rl_method.reg, ArtMethod::DeclaringClassOffset().Int32Value(), res_reg,
kNotVolatile);
LoadRefDisp(res_reg, mirror::Class::DexCacheStringsOffset().Int32Value(), res_reg,
kNotVolatile);
@@ -1173,18 +1172,18 @@ void Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, Re
if (use_declaring_class) {
RegStorage r_method = LoadCurrMethodWithHint(check_class);
- LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), check_class,
+ LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), check_class,
kNotVolatile);
LoadRefDisp(object.reg, mirror::Object::ClassOffset().Int32Value(), object_class,
kNotVolatile);
} else if (CanUseOpPcRelDexCacheArrayLoad()) {
size_t offset = dex_cache_arrays_layout_.TypeOffset(type_idx);
- OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, check_class);
+ OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, check_class, false);
LoadRefDisp(object.reg, mirror::Object::ClassOffset().Int32Value(), object_class,
kNotVolatile);
} else {
RegStorage r_method = LoadCurrMethodWithHint(check_class);
- LoadRefDisp(r_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
+ LoadRefDisp(r_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
check_class, kNotVolatile);
LoadRefDisp(object.reg, mirror::Object::ClassOffset().Int32Value(), object_class,
kNotVolatile);
@@ -1232,7 +1231,7 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know
} else if (use_declaring_class) {
RegStorage r_method = LoadCurrMethodWithHint(TargetReg(kArg1, kRef));
LoadValueDirectFixed(rl_src, ref_reg); // kArg0 <= ref
- LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
+ LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(),
class_reg, kNotVolatile);
} else {
if (can_assume_type_is_in_dex_cache) {
@@ -1242,11 +1241,11 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know
if (CanUseOpPcRelDexCacheArrayLoad()) {
size_t offset = dex_cache_arrays_layout_.TypeOffset(type_idx);
- OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, class_reg);
+ OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, class_reg, false);
} else {
RegStorage r_method = LoadCurrMethodWithHint(class_reg);
// Load dex cache entry into class_reg (kArg2)
- LoadRefDisp(r_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
+ LoadRefDisp(r_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
class_reg, kNotVolatile);
int32_t offset_of_type = ClassArray::OffsetOfElement(type_idx).Int32Value();
LoadRefDisp(class_reg, offset_of_type, class_reg, kNotVolatile);
@@ -1367,17 +1366,17 @@ void Mir2Lir::GenCheckCast(int opt_flags, uint32_t insn_idx, uint32_t type_idx,
OpRegCopy(class_reg, TargetReg(kRet0, kRef)); // Align usage with fast path
} else if (use_declaring_class) {
RegStorage method_reg = LoadCurrMethodWithHint(TargetReg(kArg1, kRef));
- LoadRefDisp(method_reg, mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
+ LoadRefDisp(method_reg, ArtMethod::DeclaringClassOffset().Int32Value(),
class_reg, kNotVolatile);
} else {
// Load dex cache entry into class_reg (kArg2)
if (CanUseOpPcRelDexCacheArrayLoad()) {
size_t offset = dex_cache_arrays_layout_.TypeOffset(type_idx);
- OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, class_reg);
+ OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, class_reg, false);
} else {
RegStorage r_method = LoadCurrMethodWithHint(class_reg);
- LoadRefDisp(r_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
+ LoadRefDisp(r_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
class_reg, kNotVolatile);
int32_t offset_of_type = ClassArray::OffsetOfElement(type_idx).Int32Value();
LoadRefDisp(class_reg, offset_of_type, class_reg, kNotVolatile);
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index ab011fc0b2..1f114cf336 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -398,7 +398,7 @@ void Mir2Lir::CallRuntimeHelperRegLocationRegLocationRegLocationRegLocation(
// TODO: Support 64-bit argument registers.
void Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) {
/*
- * Dummy up a RegLocation for the incoming StackReference<mirror::ArtMethod>
+ * Dummy up a RegLocation for the incoming ArtMethod*
* It will attempt to keep kArg0 live (or copy it to home location
* if promoted).
*/
@@ -407,10 +407,15 @@ void Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) {
rl_src.reg = TargetReg(kArg0, kRef);
rl_src.home = false;
MarkLive(rl_src);
- StoreValue(rl_method, rl_src);
+ if (cu_->target64) {
+ DCHECK(rl_method.wide);
+ StoreValueWide(rl_method, rl_src);
+ } else {
+ StoreValue(rl_method, rl_src);
+ }
// If Method* has been promoted, explicitly flush
if (rl_method.location == kLocPhysReg) {
- StoreRefDisp(TargetPtrReg(kSp), 0, rl_src.reg, kNotVolatile);
+ StoreBaseDisp(TargetPtrReg(kSp), 0, rl_src.reg, kWord, kNotVolatile);
}
if (mir_graph_->GetNumOfInVRs() == 0) {
@@ -498,7 +503,7 @@ static void CommonCallCodeLoadClassIntoArg0(const CallInfo* info, Mir2Lir* cg) {
static bool CommonCallCodeLoadCodePointerIntoInvokeTgt(const RegStorage* alt_from,
const CompilationUnit* cu, Mir2Lir* cg) {
if (cu->instruction_set != kX86 && cu->instruction_set != kX86_64) {
- int32_t offset = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
+ int32_t offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(
InstructionSetPointerSize(cu->instruction_set)).Int32Value();
// Get the compiled code address [use *alt_from or kArg0, set kInvokeTgt]
cg->LoadWordDisp(alt_from == nullptr ? cg->TargetReg(kArg0, kRef) : *alt_from, offset,
@@ -535,10 +540,12 @@ static int NextVCallInsn(CompilationUnit* cu, CallInfo* info,
break;
case 2: {
// Get this->klass_.embedded_vtable[method_idx] [usr kArg0, set kArg0]
- int32_t offset = mirror::Class::EmbeddedVTableOffset().Uint32Value() +
- method_idx * sizeof(mirror::Class::VTableEntry);
+ const size_t pointer_size = InstructionSetPointerSize(
+ cu->compiler_driver->GetInstructionSet());
+ int32_t offset = mirror::Class::EmbeddedVTableEntryOffset(
+ method_idx, pointer_size).Uint32Value();
// Load target method from embedded vtable to kArg0 [use kArg0, set kArg0]
- cg->LoadRefDisp(cg->TargetReg(kArg0, kRef), offset, cg->TargetReg(kArg0, kRef), kNotVolatile);
+ cg->LoadWordDisp(cg->TargetPtrReg(kArg0), offset, cg->TargetPtrReg(kArg0));
break;
}
case 3:
@@ -580,10 +587,12 @@ static int NextInterfaceCallInsn(CompilationUnit* cu, CallInfo* info, int state,
// Includes a null-check.
break;
case 3: { // Get target method [use kInvokeTgt, set kArg0]
- int32_t offset = mirror::Class::EmbeddedImTableOffset().Uint32Value() +
- (method_idx % mirror::Class::kImtSize) * sizeof(mirror::Class::ImTableEntry);
+ const size_t pointer_size = InstructionSetPointerSize(
+ cu->compiler_driver->GetInstructionSet());
+ int32_t offset = mirror::Class::EmbeddedImTableEntryOffset(
+ method_idx % mirror::Class::kImtSize, pointer_size).Uint32Value();
// Load target method from embedded imtable to kArg0 [use kArg0, set kArg0]
- cg->LoadRefDisp(cg->TargetReg(kArg0, kRef), offset, cg->TargetReg(kArg0, kRef), kNotVolatile);
+ cg->LoadWordDisp(cg->TargetPtrReg(kArg0), offset, cg->TargetPtrReg(kArg0));
break;
}
case 4:
@@ -967,7 +976,7 @@ bool Mir2Lir::GenInlinedReferenceGetReferent(CallInfo* info) {
RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true);
GenNullCheck(rl_obj.reg, info->opt_flags);
LoadRefDisp(rl_obj.reg, mirror::Reference::ReferentOffset().Int32Value(), rl_result.reg,
- kNotVolatile);
+ kNotVolatile);
MarkPossibleNullPointerException(info->opt_flags);
StoreValue(rl_dest, rl_result);
@@ -1418,7 +1427,7 @@ bool Mir2Lir::GenInlinedCurrentThread(CallInfo* info) {
RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true);
- if (Is64BitInstructionSet(cu_->instruction_set)) {
+ if (cu_->target64) {
LoadRefDisp(TargetPtrReg(kSelf), Thread::PeerOffset<8>().Int32Value(), rl_result.reg,
kNotVolatile);
} else {
diff --git a/compiler/dex/quick/gen_loadstore.cc b/compiler/dex/quick/gen_loadstore.cc
index 4215e8bc50..aa95e77f6d 100644
--- a/compiler/dex/quick/gen_loadstore.cc
+++ b/compiler/dex/quick/gen_loadstore.cc
@@ -42,7 +42,7 @@ LIR* Mir2Lir::LoadConstant(RegStorage r_dest, int value) {
* register liveness. That is the responsibility of the caller.
*/
void Mir2Lir::LoadValueDirect(RegLocation rl_src, RegStorage r_dest) {
- rl_src = UpdateLoc(rl_src);
+ rl_src = rl_src.wide ? UpdateLocWide(rl_src) : UpdateLoc(rl_src);
if (rl_src.location == kLocPhysReg) {
OpRegCopy(r_dest, rl_src.reg);
} else if (IsInexpensiveConstant(rl_src)) {
@@ -53,11 +53,15 @@ void Mir2Lir::LoadValueDirect(RegLocation rl_src, RegStorage r_dest) {
DCHECK((rl_src.location == kLocDalvikFrame) ||
(rl_src.location == kLocCompilerTemp));
ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
+ OpSize op_size;
if (rl_src.ref) {
- LoadRefDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, kNotVolatile);
+ op_size = kReference;
+ } else if (rl_src.wide) {
+ op_size = k64;
} else {
- Load32Disp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest);
+ op_size = k32;
}
+ LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, op_size, kNotVolatile);
}
}
@@ -337,7 +341,11 @@ void Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) {
/* Utilities to load the current Method* */
void Mir2Lir::LoadCurrMethodDirect(RegStorage r_tgt) {
- LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt);
+ if (GetCompilationUnit()->target64) {
+ LoadValueDirectWideFixed(mir_graph_->GetMethodLoc(), r_tgt);
+ } else {
+ LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt);
+ }
}
RegStorage Mir2Lir::LoadCurrMethodWithHint(RegStorage r_hint) {
@@ -355,7 +363,9 @@ RegStorage Mir2Lir::LoadCurrMethodWithHint(RegStorage r_hint) {
}
RegLocation Mir2Lir::LoadCurrMethod() {
- return LoadValue(mir_graph_->GetMethodLoc(), kRefReg);
+ return GetCompilationUnit()->target64 ?
+ LoadValueWide(mir_graph_->GetMethodLoc(), kCoreReg) :
+ LoadValue(mir_graph_->GetMethodLoc(), kRefReg);
}
RegLocation Mir2Lir::ForceTemp(RegLocation loc) {
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc
index 3d253842c9..da12d8e3bf 100644
--- a/compiler/dex/quick/mips/call_mips.cc
+++ b/compiler/dex/quick/mips/call_mips.cc
@@ -18,6 +18,7 @@
#include "codegen_mips.h"
+#include "art_method.h"
#include "base/logging.h"
#include "dex/mir_graph.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
@@ -26,7 +27,6 @@
#include "entrypoints/quick/quick_entrypoints.h"
#include "gc/accounting/card_table.h"
#include "mips_lir.h"
-#include "mirror/art_method.h"
#include "mirror/object_array-inl.h"
namespace art {
@@ -407,12 +407,12 @@ static int NextSDCallInsn(CompilationUnit* cu, CallInfo* info, int state,
RegStorage arg0_ref = cg->TargetReg(kArg0, kRef);
switch (state) {
case 0: { // Grab target method* from thread pointer
- cg->LoadRefDisp(cg->TargetPtrReg(kSelf), info->string_init_offset, arg0_ref, kNotVolatile);
+ cg->LoadWordDisp(cg->TargetPtrReg(kSelf), info->string_init_offset, arg0_ref);
break;
}
case 1: // Grab the code from the method*
if (direct_code == 0) {
- int32_t offset = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
+ int32_t offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(
InstructionSetPointerSize(cu->instruction_set)).Int32Value();
cg->LoadWordDisp(arg0_ref, offset, cg->TargetPtrReg(kInvokeTgt));
}
@@ -454,7 +454,7 @@ static int NextSDCallInsn(CompilationUnit* cu, CallInfo* info, int state,
break;
case 1: // Get method->dex_cache_resolved_methods_
cg->LoadRefDisp(arg0_ref,
- mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(),
+ ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(),
arg0_ref,
kNotVolatile);
// Set up direct code if known.
@@ -471,17 +471,18 @@ static int NextSDCallInsn(CompilationUnit* cu, CallInfo* info, int state,
}
}
break;
- case 2: // Grab target method*
+ case 2: {
+ // Grab target method*
CHECK_EQ(cu->dex_file, target_method.dex_file);
- cg->LoadRefDisp(arg0_ref,
- mirror::ObjectArray<mirror::Object>::
- OffsetOfElement(target_method.dex_method_index).Int32Value(),
- arg0_ref,
- kNotVolatile);
+ const size_t pointer_size = GetInstructionSetPointerSize(cu->instruction_set);
+ cg->LoadWordDisp(arg0_ref,
+ mirror::Array::DataOffset(pointer_size).Uint32Value() +
+ target_method.dex_method_index * pointer_size, arg0_ref);
break;
+ }
case 3: // Grab the code from the method*
if (direct_code == 0) {
- int32_t offset = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
+ int32_t offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(
InstructionSetPointerSize(cu->instruction_set)).Int32Value();
// Get the compiled code address [use *alt_from or kArg0, set kInvokeTgt]
cg->LoadWordDisp(arg0_ref, offset, cg->TargetPtrReg(kInvokeTgt));
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index e3e87ecb13..7ca03cf0ee 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -1232,6 +1232,10 @@ bool Mir2Lir::MethodBlockCodeGen(BasicBlock* bb) {
ResetRegPool();
int start_vreg = mir_graph_->GetFirstInVR();
AppendLIR(NewLIR0(kPseudoPrologueBegin));
+ DCHECK_EQ(cu_->target64, Is64BitInstructionSet(cu_->instruction_set));
+ if (cu_->target64) {
+ DCHECK(mir_graph_->GetMethodLoc().wide);
+ }
GenEntrySequence(&mir_graph_->reg_location_[start_vreg], mir_graph_->GetMethodLoc());
AppendLIR(NewLIR0(kPseudoPrologueEnd));
DCHECK_EQ(cfi_.GetCurrentCFAOffset(), frame_size_);
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index d54616f47c..73787e958e 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -982,12 +982,11 @@ class Mir2Lir {
}
// Load a reference at base + displacement and decompress into register.
LIR* LoadRefDisp(RegStorage r_base, int displacement, RegStorage r_dest,
- VolatileKind is_volatile) {
+ VolatileKind is_volatile) {
return LoadBaseDisp(r_base, displacement, r_dest, kReference, is_volatile);
}
// Load a reference at base + index and decompress into register.
- LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest,
- int scale) {
+ LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale) {
return LoadBaseIndexed(r_base, r_index, r_dest, scale, kReference);
}
// Load Dalvik value with 32-bit memory storage. If compressed object reference, decompress.
@@ -1008,12 +1007,11 @@ class Mir2Lir {
}
// Store an uncompressed reference into a compressed 32-bit container.
LIR* StoreRefDisp(RegStorage r_base, int displacement, RegStorage r_src,
- VolatileKind is_volatile) {
+ VolatileKind is_volatile) {
return StoreBaseDisp(r_base, displacement, r_src, kReference, is_volatile);
}
// Store an uncompressed reference into a compressed 32-bit container by index.
- LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src,
- int scale) {
+ LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale) {
return StoreBaseIndexed(r_base, r_index, r_src, scale, kReference);
}
// Store 32 bits, regardless of target.
@@ -1117,8 +1115,10 @@ class Mir2Lir {
* @param dex_file the dex file associated with the target dex cache.
* @param offset the offset of the element in the fixed dex cache arrays' layout.
* @param r_dest the register where to load the element.
+ * @param wide, load 64 bits if true, otherwise 32 bits.
*/
- virtual void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest);
+ virtual void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest,
+ bool wide);
// Routines that work for the generic case, but may be overriden by target.
/*
diff --git a/compiler/dex/quick/quick_cfi_test.cc b/compiler/dex/quick/quick_cfi_test.cc
index b3c73557a7..8694ebc738 100644
--- a/compiler/dex/quick/quick_cfi_test.cc
+++ b/compiler/dex/quick/quick_cfi_test.cc
@@ -100,7 +100,8 @@ class QuickCFITest : public CFITest {
}
}
m2l->AdjustSpillMask();
- m2l->GenEntrySequence(nullptr, m2l->LocCReturnRef());
+ m2l->GenEntrySequence(nullptr, m2l->GetCompilationUnit()->target64 ?
+ m2l->LocCReturnWide() : m2l->LocCReturnRef());
m2l->GenExitSequence();
m2l->HandleSlowPaths();
m2l->AssembleLIR();
diff --git a/compiler/dex/quick/quick_cfi_test_expected.inc b/compiler/dex/quick/quick_cfi_test_expected.inc
index 48109d2f44..52d66a40a8 100644
--- a/compiler/dex/quick/quick_cfi_test_expected.inc
+++ b/compiler/dex/quick/quick_cfi_test_expected.inc
@@ -34,7 +34,7 @@ static constexpr uint8_t expected_cfi_kThumb2[] = {
static constexpr uint8_t expected_asm_kArm64[] = {
0xFF, 0x03, 0x01, 0xD1, 0xE8, 0xA7, 0x01, 0x6D, 0xF3, 0xD3, 0x02, 0xA9,
- 0xFE, 0x1F, 0x00, 0xF9, 0xE0, 0x03, 0x00, 0xB9, 0xE8, 0xA7, 0x41, 0x6D,
+ 0xFE, 0x1F, 0x00, 0xF9, 0xE0, 0x03, 0x00, 0xF9, 0xE8, 0xA7, 0x41, 0x6D,
0xF3, 0xD3, 0x42, 0xA9, 0xFE, 0x1F, 0x40, 0xF9, 0xFF, 0x03, 0x01, 0x91,
0xC0, 0x03, 0x5F, 0xD6,
};
@@ -54,7 +54,7 @@ static constexpr uint8_t expected_cfi_kArm64[] = {
// 0x0000000c: .cfi_offset: r20 at cfa-16
// 0x0000000c: str lr, [sp, #56]
// 0x00000010: .cfi_offset: r30 at cfa-8
-// 0x00000010: str w0, [sp]
+// 0x00000010: str x0, [sp]
// 0x00000014: .cfi_remember_state
// 0x00000014: ldp d8, d9, [sp, #24]
// 0x00000018: .cfi_restore_extended: r72
@@ -101,15 +101,15 @@ static constexpr uint8_t expected_cfi_kX86[] = {
static constexpr uint8_t expected_asm_kX86_64[] = {
0x48, 0x83, 0xEC, 0x38, 0x48, 0x89, 0x5C, 0x24, 0x28, 0x48, 0x89, 0x6C,
0x24, 0x30, 0xF2, 0x44, 0x0F, 0x11, 0x64, 0x24, 0x18, 0xF2, 0x44, 0x0F,
- 0x11, 0x6C, 0x24, 0x20, 0x48, 0x8B, 0xC7, 0x89, 0x3C, 0x24, 0x48, 0x8B,
- 0x5C, 0x24, 0x28, 0x48, 0x8B, 0x6C, 0x24, 0x30, 0xF2, 0x44, 0x0F, 0x10,
- 0x64, 0x24, 0x18, 0xF2, 0x44, 0x0F, 0x10, 0x6C, 0x24, 0x20, 0x48, 0x83,
- 0xC4, 0x38, 0xC3, 0x00,
+ 0x11, 0x6C, 0x24, 0x20, 0x48, 0x8B, 0xC7, 0x48, 0x89, 0x3C, 0x24, 0x48,
+ 0x8B, 0x5C, 0x24, 0x28, 0x48, 0x8B, 0x6C, 0x24, 0x30, 0xF2, 0x44, 0x0F,
+ 0x10, 0x64, 0x24, 0x18, 0xF2, 0x44, 0x0F, 0x10, 0x6C, 0x24, 0x20, 0x48,
+ 0x83, 0xC4, 0x38, 0xC3,
};
static constexpr uint8_t expected_cfi_kX86_64[] = {
0x44, 0x0E, 0x40, 0x45, 0x83, 0x06, 0x45, 0x86, 0x04, 0x47, 0x9D, 0x0A,
- 0x47, 0x9E, 0x08, 0x46, 0x0A, 0x45, 0xC3, 0x45, 0xC6, 0x47, 0xDD, 0x47,
- 0xDE, 0x44, 0x0E, 0x08, 0x42, 0x0B, 0x0E, 0x40,
+ 0x47, 0x9E, 0x08, 0x47, 0x0A, 0x45, 0xC3, 0x45, 0xC6, 0x47, 0xDD, 0x47,
+ 0xDE, 0x44, 0x0E, 0x08, 0x41, 0x0B, 0x0E, 0x40,
};
// 0x00000000: subq rsp, 56
// 0x00000004: .cfi_def_cfa_offset: 64
@@ -122,20 +122,19 @@ static constexpr uint8_t expected_cfi_kX86_64[] = {
// 0x00000015: movsd [rsp + 32], xmm13
// 0x0000001c: .cfi_offset: r30 at cfa-32
// 0x0000001c: movq rax, rdi
-// 0x0000001f: mov [rsp], edi
-// 0x00000022: .cfi_remember_state
-// 0x00000022: movq rbx, [rsp + 40]
-// 0x00000027: .cfi_restore: r3
-// 0x00000027: movq rbp, [rsp + 48]
-// 0x0000002c: .cfi_restore: r6
-// 0x0000002c: movsd xmm12, [rsp + 24]
-// 0x00000033: .cfi_restore: r29
-// 0x00000033: movsd xmm13, [rsp + 32]
-// 0x0000003a: .cfi_restore: r30
-// 0x0000003a: addq rsp, 56
-// 0x0000003e: .cfi_def_cfa_offset: 8
-// 0x0000003e: ret
-// 0x0000003f: addb al, al
+// 0x0000001f: movq [rsp], rdi
+// 0x00000023: .cfi_remember_state
+// 0x00000023: movq rbx, [rsp + 40]
+// 0x00000028: .cfi_restore: r3
+// 0x00000028: movq rbp, [rsp + 48]
+// 0x0000002d: .cfi_restore: r6
+// 0x0000002d: movsd xmm12, [rsp + 24]
+// 0x00000034: .cfi_restore: r29
+// 0x00000034: movsd xmm13, [rsp + 32]
+// 0x0000003b: .cfi_restore: r30
+// 0x0000003b: addq rsp, 56
+// 0x0000003f: .cfi_def_cfa_offset: 8
+// 0x0000003f: ret
// 0x00000040: .cfi_restore_state
// 0x00000040: .cfi_def_cfa_offset: 64
@@ -172,7 +171,7 @@ static constexpr uint8_t expected_cfi_kMips[] = {
// 0x00000028: .cfi_restore: r31
// 0x00000028: addiu r29, r29, 64
// 0x0000002c: .cfi_def_cfa_offset: 0
-// 0x0000002c: jalr r0, r31
+// 0x0000002c: jr r31
// 0x00000030: nop
// 0x00000034: .cfi_restore_state
// 0x00000034: .cfi_def_cfa_offset: 64
@@ -180,7 +179,7 @@ static constexpr uint8_t expected_cfi_kMips[] = {
static constexpr uint8_t expected_asm_kMips64[] = {
0xE8, 0xFF, 0xBD, 0x67, 0x10, 0x00, 0xB2, 0xFF, 0x08, 0x00, 0xB3, 0xFF,
0x00, 0x00, 0xBF, 0xFF, 0xD8, 0xFF, 0xBD, 0x67, 0x25, 0x10, 0x80, 0x00,
- 0x00, 0x00, 0xA4, 0xAF, 0x38, 0x00, 0xB2, 0xDF, 0x30, 0x00, 0xB3, 0xDF,
+ 0x00, 0x00, 0xA4, 0xFF, 0x38, 0x00, 0xB2, 0xDF, 0x30, 0x00, 0xB3, 0xDF,
0x28, 0x00, 0xBF, 0xDF, 0x40, 0x00, 0xBD, 0x67, 0x09, 0x00, 0xE0, 0x03,
0x00, 0x00, 0x00, 0x00,
};
@@ -200,7 +199,7 @@ static constexpr uint8_t expected_cfi_kMips64[] = {
// 0x00000010: daddiu r29, r29, -40
// 0x00000014: .cfi_def_cfa_offset: 64
// 0x00000014: or r2, r4, r0
-// 0x00000018: sw r4, +0(r29)
+// 0x00000018: sd r4, +0(r29)
// 0x0000001c: .cfi_remember_state
// 0x0000001c: ld r18, +56(r29)
// 0x00000020: .cfi_restore: r18
@@ -214,4 +213,3 @@ static constexpr uint8_t expected_cfi_kMips64[] = {
// 0x00000030: nop
// 0x00000034: .cfi_restore_state
// 0x00000034: .cfi_def_cfa_offset: 64
-
diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc
index 7ca438225f..58236e2216 100644
--- a/compiler/dex/quick/quick_compiler.cc
+++ b/compiler/dex/quick/quick_compiler.cc
@@ -18,6 +18,7 @@
#include <cstdint>
+#include "art_method-inl.h"
#include "base/dumpable.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -37,7 +38,6 @@
#include "elf_writer_quick.h"
#include "jni/quick/jni_compiler.h"
#include "mir_to_lir.h"
-#include "mirror/art_method-inl.h"
#include "mirror/object.h"
#include "runtime.h"
@@ -787,7 +787,7 @@ CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags,
return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
}
-uintptr_t QuickCompiler::GetEntryPointOf(mirror::ArtMethod* method) const {
+uintptr_t QuickCompiler::GetEntryPointOf(ArtMethod* method) const {
return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet())));
}
diff --git a/compiler/dex/quick/quick_compiler.h b/compiler/dex/quick/quick_compiler.h
index 8d2c324a70..43dd5786af 100644
--- a/compiler/dex/quick/quick_compiler.h
+++ b/compiler/dex/quick/quick_compiler.h
@@ -49,7 +49,7 @@ class QuickCompiler : public Compiler {
uint32_t method_idx,
const DexFile& dex_file) const OVERRIDE;
- uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const OVERRIDE
+ uintptr_t GetEntryPointOf(ArtMethod* method) const OVERRIDE
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static Mir2Lir* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit);
diff --git a/compiler/dex/quick/x86/call_x86.cc b/compiler/dex/quick/x86/call_x86.cc
index 249575761e..43167a187f 100644
--- a/compiler/dex/quick/x86/call_x86.cc
+++ b/compiler/dex/quick/x86/call_x86.cc
@@ -18,13 +18,13 @@
#include "codegen_x86.h"
+#include "art_method.h"
#include "base/logging.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
#include "dex/quick/mir_to_lir-inl.h"
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
#include "gc/accounting/card_table.h"
-#include "mirror/art_method.h"
#include "mirror/object_array-inl.h"
#include "utils/dex_cache_arrays_layout-inl.h"
#include "x86_lir.h"
@@ -379,7 +379,8 @@ int X86Mir2Lir::X86NextSDCallInsn(CompilationUnit* cu, CallInfo* info,
case 0: {
CHECK_EQ(cu->dex_file, target_method.dex_file);
size_t offset = cg->dex_cache_arrays_layout_.MethodOffset(target_method.dex_method_index);
- cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, cg->TargetReg(kArg0, kRef));
+ cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, cg->TargetReg(kArg0, kRef),
+ cu->target64);
break;
}
default:
@@ -394,18 +395,20 @@ int X86Mir2Lir::X86NextSDCallInsn(CompilationUnit* cu, CallInfo* info,
break;
case 1: // Get method->dex_cache_resolved_methods_
cg->LoadRefDisp(arg0_ref,
- mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(),
+ ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(),
arg0_ref,
kNotVolatile);
break;
- case 2: // Grab target method*
+ case 2: {
+ // Grab target method*
CHECK_EQ(cu->dex_file, target_method.dex_file);
- cg->LoadRefDisp(arg0_ref,
- mirror::ObjectArray<mirror::Object>::OffsetOfElement(
- target_method.dex_method_index).Int32Value(),
- arg0_ref,
- kNotVolatile);
+ const size_t pointer_size = GetInstructionSetPointerSize(cu->instruction_set);
+ cg->LoadWordDisp(arg0_ref,
+ mirror::Array::DataOffset(pointer_size).Uint32Value() +
+ target_method.dex_method_index * pointer_size,
+ arg0_ref);
break;
+ }
default:
return -1;
}
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index 5a465203bc..11d9d4ac34 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -105,7 +105,8 @@ class X86Mir2Lir FINAL : public Mir2Lir {
void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE;
bool CanUseOpPcRelDexCacheArrayLoad() const OVERRIDE;
- void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest) OVERRIDE;
+ void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, bool wide)
+ OVERRIDE;
void GenImplicitNullCheck(RegStorage reg, int opt_flags) OVERRIDE;
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 9bbb5f84be..d993d934a5 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -18,11 +18,11 @@
#include "codegen_x86.h"
+#include "art_method.h"
#include "base/bit_utils.h"
#include "base/logging.h"
#include "dex/quick/mir_to_lir-inl.h"
#include "dex/reg_storage_eq.h"
-#include "mirror/art_method.h"
#include "mirror/array-inl.h"
#include "x86_lir.h"
@@ -1410,16 +1410,18 @@ RegStorage X86Mir2Lir::GetPcAndAnchor(LIR** anchor, RegStorage r_tmp) {
}
}
-void X86Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset,
- RegStorage r_dest) {
+void X86Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest,
+ bool wide) {
if (cu_->target64) {
- LIR* mov = NewLIR3(kX86Mov32RM, r_dest.GetReg(), kRIPReg, kDummy32BitOffset);
+ LIR* mov = NewLIR3(wide ? kX86Mov64RM : kX86Mov32RM, r_dest.GetReg(), kRIPReg,
+ kDummy32BitOffset);
mov->flags.fixup = kFixupLabel;
mov->operands[3] = WrapPointer(dex_file);
mov->operands[4] = offset;
mov->target = mov; // Used for pc_insn_offset (not used by x86-64 relative patcher).
dex_cache_access_insns_.push_back(mov);
} else {
+ CHECK(!wide) << "Unsupported";
// Get the PC to a register and get the anchor. Use r_dest for the temp if needed.
LIR* anchor;
RegStorage r_pc = GetPcAndAnchor(&anchor, r_dest);
@@ -3022,20 +3024,20 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx,
if (rl_method.location == kLocPhysReg) {
if (use_declaring_class) {
- LoadRefDisp(rl_method.reg, mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
+ LoadRefDisp(rl_method.reg, ArtMethod::DeclaringClassOffset().Int32Value(),
check_class, kNotVolatile);
} else {
- LoadRefDisp(rl_method.reg, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
+ LoadRefDisp(rl_method.reg, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
check_class, kNotVolatile);
LoadRefDisp(check_class, offset_of_type, check_class, kNotVolatile);
}
} else {
LoadCurrMethodDirect(check_class);
if (use_declaring_class) {
- LoadRefDisp(check_class, mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
+ LoadRefDisp(check_class, ArtMethod::DeclaringClassOffset().Int32Value(),
check_class, kNotVolatile);
} else {
- LoadRefDisp(check_class, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
+ LoadRefDisp(check_class, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
check_class, kNotVolatile);
LoadRefDisp(check_class, offset_of_type, check_class, kNotVolatile);
}
@@ -3059,7 +3061,7 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx,
}
void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_lhs, RegLocation rl_rhs, int flags) {
+ RegLocation rl_lhs, RegLocation rl_rhs, int flags) {
OpKind op = kOpBkpt;
bool is_div_rem = false;
bool unary = false;
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 2f211da264..c62cd47315 100755
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -21,6 +21,7 @@
#include <string>
#include "arch/instruction_set_features.h"
+#include "art_method.h"
#include "backend_x86.h"
#include "base/logging.h"
#include "dex/compiler_ir.h"
@@ -28,7 +29,6 @@
#include "dex/reg_storage_eq.h"
#include "driver/compiler_driver.h"
#include "mirror/array-inl.h"
-#include "mirror/art_method.h"
#include "mirror/string.h"
#include "oat.h"
#include "x86_lir.h"
@@ -744,6 +744,7 @@ void X86Mir2Lir::SpillCoreRegs() {
const RegStorage rs_rSP = cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32;
for (int reg = 0; mask != 0u; mask >>= 1, reg++) {
if ((mask & 0x1) != 0u) {
+ DCHECK_NE(offset, 0) << "offset 0 should be for method";
RegStorage r_src = cu_->target64 ? RegStorage::Solo64(reg) : RegStorage::Solo32(reg);
StoreBaseDisp(rs_rSP, offset, r_src, size, kNotVolatile);
cfi_.RelOffset(DwarfCoreReg(cu_->target64, reg), offset);
@@ -1026,7 +1027,7 @@ LIR* X86Mir2Lir::GenCallInsn(const MirMethodLoweringInfo& method_info) {
call_insn = CallWithLinkerFixup(method_info.GetTargetMethod(), method_info.GetSharpType());
} else {
call_insn = OpMem(kOpBlx, TargetReg(kArg0, kRef),
- mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
+ ArtMethod::EntryPointFromQuickCompiledCodeOffset(
cu_->target64 ? 8 : 4).Int32Value());
}
} else {
@@ -1103,7 +1104,7 @@ void X86Mir2Lir::InstallLiteralPools() {
// PC-relative references to dex cache arrays.
for (LIR* p : dex_cache_access_insns_) {
- DCHECK(p->opcode == kX86Mov32RM);
+ DCHECK(p->opcode == kX86Mov32RM || p->opcode == kX86Mov64RM);
const DexFile* dex_file = UnwrapPointer<DexFile>(p->operands[3]);
uint32_t offset = p->operands[4];
// The offset to patch is the last 4 bytes of the instruction.
diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h
index 57db0158e4..d6a6a60d3d 100644
--- a/compiler/dex/quick/x86/x86_lir.h
+++ b/compiler/dex/quick/x86/x86_lir.h
@@ -82,7 +82,7 @@ namespace art {
* | IN[ins-1] | {Note: resides in caller's frame}
* | . |
* | IN[0] |
- * | caller's Method* |
+ * | caller's ArtMethod* |
* +===========================+ {Note: start of callee's frame}
* | return address | {pushed by call}
* | spill region | {variable sized}
@@ -104,7 +104,7 @@ namespace art {
* | OUT[outs-2] |
* | . |
* | OUT[0] |
- * | StackReference<ArtMethod> | <<== sp w/ 16-byte alignment
+ * | ArtMethod* | <<== sp w/ 16-byte alignment
* +===========================+
*/