ART: Move DexCache arrays to native.
This CL has a companion CL in libcore/
https://android-review.googlesource.com/162985
Change-Id: Icbc9e20ad1b565e603195b12714762bb446515fa
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 503187b..f4cf9b5 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -129,12 +129,12 @@
}
size_t CodeGenerator::GetCacheOffset(uint32_t index) {
- return mirror::ObjectArray<mirror::Object>::OffsetOfElement(index).SizeValue();
+ return sizeof(GcRoot<mirror::Object>) * index;
}
size_t CodeGenerator::GetCachePointerOffset(uint32_t index) {
auto pointer_size = InstructionSetPointerSize(GetInstructionSet());
- return mirror::Array::DataOffset(pointer_size).Uint32Value() + pointer_size * index;
+ return pointer_size * index;
}
void CodeGenerator::CompileBaseline(CodeAllocator* allocator, bool is_leaf) {
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 9de9abf..5b7eea6 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -4231,9 +4231,9 @@
__ LoadFromOffset(kLoadWord,
out,
current_method,
- ArtMethod::DexCacheResolvedTypesOffset().Int32Value());
+ ArtMethod::DexCacheResolvedTypesOffset(kArmPointerSize).Int32Value());
__ LoadFromOffset(kLoadWord, out, out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex()));
- __ MaybeUnpoisonHeapReference(out);
+ // TODO: We will need a read barrier here.
SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM(
cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck());
@@ -4293,9 +4293,8 @@
__ LoadFromOffset(
kLoadWord, out, current_method, ArtMethod::DeclaringClassOffset().Int32Value());
__ LoadFromOffset(kLoadWord, out, out, mirror::Class::DexCacheStringsOffset().Int32Value());
- __ MaybeUnpoisonHeapReference(out);
__ LoadFromOffset(kLoadWord, out, out, CodeGenerator::GetCacheOffset(load->GetStringIndex()));
- __ MaybeUnpoisonHeapReference(out);
+ // TODO: We will need a read barrier here.
__ CompareAndBranchIfZero(out, slow_path->GetEntryLabel());
__ Bind(slow_path->GetExitLabel());
}
@@ -4570,7 +4569,8 @@
}
// temp = current_method->dex_cache_resolved_methods_;
__ LoadFromOffset(
- kLoadWord, reg, method_reg, ArtMethod::DexCacheResolvedMethodsOffset().Int32Value());
+ kLoadWord, reg, method_reg, ArtMethod::DexCacheResolvedMethodsOffset(
+ kArmPointerSize).Int32Value());
// temp = temp[index_in_cache]
uint32_t index_in_cache = invoke->GetTargetMethod().dex_method_index;
__ LoadFromOffset(kLoadWord, reg, reg, CodeGenerator::GetCachePointerOffset(index_in_cache));
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 25b3ea2..b18fb6e 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -2446,8 +2446,9 @@
}
// temp = current_method->dex_cache_resolved_methods_;
- __ Ldr(reg.W(), MemOperand(method_reg.X(),
- ArtMethod::DexCacheResolvedMethodsOffset().Int32Value()));
+ __ Ldr(reg.X(),
+ MemOperand(method_reg.X(),
+ ArtMethod::DexCacheResolvedMethodsOffset(kArm64WordSize).Int32Value()));
// temp = temp[index_in_cache];
uint32_t index_in_cache = invoke->GetTargetMethod().dex_method_index;
__ Ldr(reg.X(), MemOperand(reg.X(), GetCachePointerOffset(index_in_cache)));
@@ -2620,9 +2621,10 @@
__ Ldr(out, MemOperand(current_method, ArtMethod::DeclaringClassOffset().Int32Value()));
} else {
DCHECK(cls->CanCallRuntime());
- __ Ldr(out, MemOperand(current_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value()));
- __ Ldr(out, HeapOperand(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())));
- GetAssembler()->MaybeUnpoisonHeapReference(out.W());
+ MemberOffset resolved_types_offset = ArtMethod::DexCacheResolvedTypesOffset(kArm64PointerSize);
+ __ Ldr(out.X(), MemOperand(current_method, resolved_types_offset.Int32Value()));
+ __ Ldr(out, MemOperand(out.X(), CodeGenerator::GetCacheOffset(cls->GetTypeIndex())));
+ // TODO: We will need a read barrier here.
SlowPathCodeARM64* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM64(
cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck());
@@ -2681,10 +2683,9 @@
Register out = OutputRegister(load);
Register current_method = InputRegisterAt(load, 0);
__ Ldr(out, MemOperand(current_method, ArtMethod::DeclaringClassOffset().Int32Value()));
- __ Ldr(out, HeapOperand(out, mirror::Class::DexCacheStringsOffset()));
- GetAssembler()->MaybeUnpoisonHeapReference(out.W());
- __ Ldr(out, HeapOperand(out, CodeGenerator::GetCacheOffset(load->GetStringIndex())));
- GetAssembler()->MaybeUnpoisonHeapReference(out.W());
+ __ Ldr(out.X(), HeapOperand(out, mirror::Class::DexCacheStringsOffset()));
+ __ Ldr(out, MemOperand(out.X(), CodeGenerator::GetCacheOffset(load->GetStringIndex())));
+ // TODO: We will need a read barrier here.
__ Cbz(out, slow_path->GetEntryLabel());
__ Bind(slow_path->GetExitLabel());
}
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index 093d786..1528d09 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -2445,10 +2445,10 @@
}
// temp = temp->dex_cache_resolved_methods_;
- __ LoadFromOffset(kLoadUnsignedWord,
+ __ LoadFromOffset(kLoadDoubleword,
reg,
method_reg,
- ArtMethod::DexCacheResolvedMethodsOffset().Int32Value());
+ ArtMethod::DexCacheResolvedMethodsOffset(kMips64PointerSize).Int32Value());
// temp = temp[index_in_cache]
uint32_t index_in_cache = invoke->GetTargetMethod().dex_method_index;
__ LoadFromOffset(kLoadDoubleword,
@@ -2549,9 +2549,10 @@
ArtMethod::DeclaringClassOffset().Int32Value());
} else {
DCHECK(cls->CanCallRuntime());
- __ LoadFromOffset(kLoadUnsignedWord, out, current_method,
- ArtMethod::DexCacheResolvedTypesOffset().Int32Value());
+ __ LoadFromOffset(kLoadDoubleword, out, current_method,
+ ArtMethod::DexCacheResolvedTypesOffset(kMips64PointerSize).Int32Value());
__ LoadFromOffset(kLoadUnsignedWord, out, out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex()));
+ // TODO: We will need a read barrier here.
SlowPathCodeMIPS64* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathMIPS64(
cls,
cls,
@@ -2614,8 +2615,9 @@
GpuRegister current_method = locations->InAt(0).AsRegister<GpuRegister>();
__ LoadFromOffset(kLoadUnsignedWord, out, current_method,
ArtMethod::DeclaringClassOffset().Int32Value());
- __ LoadFromOffset(kLoadUnsignedWord, out, out, mirror::Class::DexCacheStringsOffset().Int32Value());
+ __ LoadFromOffset(kLoadDoubleword, out, out, mirror::Class::DexCacheStringsOffset().Int32Value());
__ LoadFromOffset(kLoadUnsignedWord, out, out, CodeGenerator::GetCacheOffset(load->GetStringIndex()));
+ // TODO: We will need a read barrier here.
__ Beqzc(out, slow_path->GetEntryLabel());
__ Bind(slow_path->GetExitLabel());
}
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 72c690d..4fa7b28 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -3545,7 +3545,8 @@
__ movl(reg, Address(ESP, kCurrentMethodStackOffset));
}
// temp = temp->dex_cache_resolved_methods_;
- __ movl(reg, Address(method_reg, ArtMethod::DexCacheResolvedMethodsOffset().Int32Value()));
+ __ movl(reg, Address(method_reg,
+ ArtMethod::DexCacheResolvedMethodsOffset(kX86PointerSize).Int32Value()));
// temp = temp[index_in_cache]
uint32_t index_in_cache = invoke->GetTargetMethod().dex_method_index;
__ movl(reg, Address(reg, CodeGenerator::GetCachePointerOffset(index_in_cache)));
@@ -4719,9 +4720,9 @@
} else {
DCHECK(cls->CanCallRuntime());
__ movl(out, Address(
- current_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value()));
+ current_method, ArtMethod::DexCacheResolvedTypesOffset(kX86PointerSize).Int32Value()));
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())));
- __ MaybeUnpoisonHeapReference(out);
+ // TODO: We will need a read barrier here.
SlowPathCodeX86* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathX86(
cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck());
@@ -4779,9 +4780,8 @@
Register current_method = locations->InAt(0).AsRegister<Register>();
__ movl(out, Address(current_method, ArtMethod::DeclaringClassOffset().Int32Value()));
__ movl(out, Address(out, mirror::Class::DexCacheStringsOffset().Int32Value()));
- __ MaybeUnpoisonHeapReference(out);
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(load->GetStringIndex())));
- __ MaybeUnpoisonHeapReference(out);
+ // TODO: We will need a read barrier here.
__ testl(out, out);
__ j(kEqual, slow_path->GetEntryLabel());
__ Bind(slow_path->GetExitLabel());
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 820ec78..29bad12 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -450,8 +450,9 @@
__ movq(reg, Address(CpuRegister(RSP), kCurrentMethodStackOffset));
}
// temp = temp->dex_cache_resolved_methods_;
- __ movl(reg, Address(CpuRegister(method_reg),
- ArtMethod::DexCacheResolvedMethodsOffset().SizeValue()));
+ __ movq(reg,
+ Address(CpuRegister(method_reg),
+ ArtMethod::DexCacheResolvedMethodsOffset(kX86_64PointerSize).SizeValue()));
// temp = temp[index_in_cache]
uint32_t index_in_cache = invoke->GetTargetMethod().dex_method_index;
__ movq(reg, Address(reg, CodeGenerator::GetCachePointerOffset(index_in_cache)));
@@ -4550,10 +4551,10 @@
__ movl(out, Address(current_method, ArtMethod::DeclaringClassOffset().Int32Value()));
} else {
DCHECK(cls->CanCallRuntime());
- __ movl(out, Address(
- current_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value()));
+ __ movq(out, Address(
+ current_method, ArtMethod::DexCacheResolvedTypesOffset(kX86_64PointerSize).Int32Value()));
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())));
- __ MaybeUnpoisonHeapReference(out);
+ // TODO: We will need a read barrier here.
SlowPathCodeX86_64* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathX86_64(
cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck());
@@ -4601,10 +4602,9 @@
CpuRegister out = locations->Out().AsRegister<CpuRegister>();
CpuRegister current_method = locations->InAt(0).AsRegister<CpuRegister>();
__ movl(out, Address(current_method, ArtMethod::DeclaringClassOffset().Int32Value()));
- __ movl(out, Address(out, mirror::Class::DexCacheStringsOffset().Int32Value()));
- __ MaybeUnpoisonHeapReference(out);
+ __ movq(out, Address(out, mirror::Class::DexCacheStringsOffset().Int32Value()));
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(load->GetStringIndex())));
- __ MaybeUnpoisonHeapReference(out);
+ // TODO: We will need a read barrier here.
__ testl(out, out);
__ j(kEqual, slow_path->GetEntryLabel());
__ Bind(slow_path->GetExitLabel());
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 112d42e..3f90676 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -496,8 +496,9 @@
// TODO: we could be more precise by merging the phi inputs but that requires
// some functionality from the reference type propagation.
DCHECK(return_replacement->IsPhi());
+ size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
ReferenceTypeInfo::TypeHandle return_handle =
- handles_->NewHandle(resolved_method->GetReturnType());
+ handles_->NewHandle(resolved_method->GetReturnType(true /* resolve */, pointer_size));
return_replacement->SetReferenceTypeInfo(ReferenceTypeInfo::Create(
return_handle, return_handle->IsFinal() /* is_exact */));
}
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 516638b..ef753ed 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -637,9 +637,9 @@
ScopedObjectAccess soa(Thread::Current());
ClassLinker* cl = Runtime::Current()->GetClassLinker();
mirror::DexCache* dex_cache = cl->FindDexCache(soa.Self(), instr->GetDexFile());
- ArtMethod* method = dex_cache->GetResolvedMethod(
- instr->GetDexMethodIndex(), cl->GetImagePointerSize());
- mirror::Class* klass = (method == nullptr) ? nullptr : method->GetReturnType(false);
+ size_t pointer_size = cl->GetImagePointerSize();
+ ArtMethod* method = dex_cache->GetResolvedMethod(instr->GetDexMethodIndex(), pointer_size);
+ mirror::Class* klass = (method == nullptr) ? nullptr : method->GetReturnType(false, pointer_size);
SetClassAsTypeInfo(instr, klass, /* is_exact */ false);
}