summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/exception_test.cc3
-rw-r--r--compiler/optimizing/optimizing_compiler.cc2
-rw-r--r--dex2oat/linker/image_writer.cc4
-rw-r--r--openjdkjvmti/ti_method.cc9
-rw-r--r--openjdkjvmti/ti_redefine.cc5
-rw-r--r--runtime/art_method-inl.h11
-rw-r--r--runtime/art_method.cc2
-rw-r--r--runtime/art_method.h27
-rw-r--r--runtime/cha.cc3
-rw-r--r--runtime/class_linker.cc34
-rw-r--r--runtime/dex/dex_file_annotations.cc2
-rw-r--r--runtime/gc/space/image_space.cc6
-rw-r--r--runtime/interpreter/interpreter.cc2
-rw-r--r--runtime/interpreter/mterp/arm64ng/main.S11
-rw-r--r--runtime/interpreter/mterp/x86_64ng/main.S16
-rw-r--r--tools/cpp-define-generator/art_method.def4
16 files changed, 84 insertions, 57 deletions
diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc
index 7d56da07fb..9212ea6c90 100644
--- a/compiler/exception_test.cc
+++ b/compiler/exception_test.cc
@@ -17,6 +17,7 @@
#include <memory>
#include <type_traits>
+#include "art_method-inl.h"
#include "base/arena_allocator.h"
#include "base/callee_save_type.h"
#include "base/enums.h"
@@ -128,7 +129,7 @@ class ExceptionTest : public CommonRuntimeTest {
TEST_F(ExceptionTest, FindCatchHandler) {
ScopedObjectAccess soa(Thread::Current());
- CodeItemDataAccessor accessor(*dex_, dex_->GetCodeItem(method_f_->GetCodeItemOffset()));
+ CodeItemDataAccessor accessor(*dex_, method_f_->GetCodeItem());
ASSERT_TRUE(accessor.HasCodeItem());
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 392aaddaa6..3c168bad65 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -1238,7 +1238,7 @@ bool OptimizingCompiler::JitCompile(Thread* self,
const DexFile* dex_file = method->GetDexFile();
const uint16_t class_def_idx = method->GetClassDefIndex();
- const dex::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
+ const dex::CodeItem* code_item = method->GetCodeItem();
const uint32_t method_idx = method->GetDexMethodIndex();
const uint32_t access_flags = method->GetAccessFlags();
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index fbdffa8502..42c570f0a0 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -3473,8 +3473,10 @@ void ImageWriter::CopyAndFixupMethod(ArtMethod* orig,
StubType stub_type = orig->IsCriticalNative() ? StubType::kJNIDlsymLookupCriticalTrampoline
: StubType::kJNIDlsymLookupTrampoline;
copy->SetEntryPointFromJniPtrSize(GetOatAddress(stub_type), target_ptr_size_);
- } else {
+ } else if (!orig->HasCodeItem()) {
CHECK(copy->GetDataPtrSize(target_ptr_size_) == nullptr);
+ } else {
+ CHECK(copy->GetDataPtrSize(target_ptr_size_) != nullptr);
}
}
}
diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc
index e7f071fac8..f2646c6c45 100644
--- a/openjdkjvmti/ti_method.cc
+++ b/openjdkjvmti/ti_method.cc
@@ -190,7 +190,8 @@ jvmtiError MethodUtil::GetArgumentsSize(jvmtiEnv* env ATTRIBUTE_UNUSED,
return ERR(NONE);
}
- DCHECK_NE(art_method->GetCodeItemOffset(), 0u);
+ DCHECK(art_method->HasCodeItem());
+ DCHECK_NE(art_method->GetCodeItem(), nullptr);
*size_ptr = art_method->DexInstructionData().InsSize();
return ERR(NONE);
@@ -306,7 +307,8 @@ jvmtiError MethodUtil::GetMaxLocals(jvmtiEnv* env ATTRIBUTE_UNUSED,
return ERR(NONE);
}
- DCHECK_NE(art_method->GetCodeItemOffset(), 0u);
+ DCHECK(art_method->HasCodeItem());
+ DCHECK_NE(art_method->GetCodeItem(), nullptr);
*max_ptr = art_method->DexInstructionData().RegistersSize();
return ERR(NONE);
@@ -420,7 +422,8 @@ jvmtiError MethodUtil::GetMethodLocation(jvmtiEnv* env ATTRIBUTE_UNUSED,
return ERR(NONE);
}
- DCHECK_NE(art_method->GetCodeItemOffset(), 0u);
+ DCHECK(art_method->HasCodeItem());
+ DCHECK_NE(art_method->GetCodeItem(), nullptr);
*start_location_ptr = 0;
*end_location_ptr = art_method->DexInstructions().InsnsSizeInCodeUnits() - 1;
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index d442799379..afaea6279d 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -2583,7 +2583,10 @@ void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class>
uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
method.SetDexMethodIndex(dex_method_idx);
linker->SetEntryPointsToInterpreter(&method);
- method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(class_def, dex_method_idx));
+ if (method.HasCodeItem()) {
+ method.SetCodeItem(
+ dex_file_->GetCodeItem(dex_file_->FindCodeItemOffset(class_def, dex_method_idx)));
+ }
// Clear all the intrinsics related flags.
method.SetNotIntrinsic();
}
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 03b4ce9078..01fa33fc65 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -223,7 +223,14 @@ inline ObjPtr<mirror::String> ArtMethod::ResolveNameString() {
}
inline const dex::CodeItem* ArtMethod::GetCodeItem() {
- return GetDexFile()->GetCodeItem(GetCodeItemOffset());
+ if (!HasCodeItem()) {
+ return nullptr;
+ }
+ Runtime* runtime = Runtime::Current();
+ PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
+ return runtime->IsAotCompiler()
+ ? GetDexFile()->GetCodeItem(reinterpret_cast32<uint32_t>(GetDataPtrSize(pointer_size)))
+ : reinterpret_cast<const dex::CodeItem*>(GetDataPtrSize(pointer_size));
}
inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx) {
@@ -384,8 +391,6 @@ inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, PointerSize poi
if (old_native_code != new_native_code) {
SetEntryPointFromJniPtrSize(new_native_code, pointer_size);
}
- } else {
- DCHECK(GetDataPtrSize(pointer_size) == nullptr);
}
const void* old_code = GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
const void* new_code = visitor(old_code);
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 45a6938694..0a824e3374 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -771,7 +771,7 @@ void ArtMethod::CopyFrom(ArtMethod* src, PointerSize image_pointer_size) {
}
// Clear the data pointer, it will be set if needed by the caller.
- if (!src->IsNative()) {
+ if (!src->HasCodeItem() && !src->IsNative()) {
SetDataPtrSize(nullptr, image_pointer_size);
}
// Clear hotness to let the JIT properly decide when to compile this method.
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 6050f003c0..30357f7c4a 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -78,7 +78,7 @@ class ArtMethod final {
// constexpr, and ensure that the value is correct in art_method.cc.
static constexpr uint32_t kRuntimeMethodDexMethodIndex = 0xFFFFFFFF;
- ArtMethod() : access_flags_(0), dex_code_item_offset_(0), dex_method_index_(0),
+ ArtMethod() : access_flags_(0), dex_method_index_(0),
method_index_(0), hotness_count_(0) { }
ArtMethod(ArtMethod* src, PointerSize image_pointer_size) {
@@ -419,15 +419,6 @@ class ArtMethod final {
return MemberOffset(OFFSETOF_MEMBER(ArtMethod, imt_index_));
}
- uint32_t GetCodeItemOffset() const {
- return dex_code_item_offset_;
- }
-
- void SetCodeItemOffset(uint32_t new_code_off) REQUIRES_SHARED(Locks::mutator_lock_) {
- // Not called within a transaction.
- dex_code_item_offset_ = new_code_off;
- }
-
// Number of 32bit registers that would be required to hold all the arguments
static size_t NumArgRegisters(const char* shorty);
@@ -587,6 +578,15 @@ class ArtMethod final {
return dex_method_index_ == kRuntimeMethodDexMethodIndex;
}
+ bool HasCodeItem() REQUIRES_SHARED(Locks::mutator_lock_) {
+ return !IsRuntimeMethod() && !IsNative() && !IsProxyMethod() && !IsAbstract();
+ }
+
+ void SetCodeItem(const dex::CodeItem* code_item) REQUIRES_SHARED(Locks::mutator_lock_) {
+ DCHECK(HasCodeItem());
+ SetDataPtrSize(code_item, kRuntimePointerSize);
+ }
+
// Is this a hand crafted method used for something like describing callee saves?
bool IsCalleeSaveMethod() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -742,7 +742,6 @@ class ArtMethod final {
DCHECK(IsImagePointerSize(kRuntimePointerSize));
visitor(this, &declaring_class_, "declaring_class_");
visitor(this, &access_flags_, "access_flags_");
- visitor(this, &dex_code_item_offset_, "dex_code_item_offset_");
visitor(this, &dex_method_index_, "dex_method_index_");
visitor(this, &method_index_, "method_index_");
visitor(this, &hotness_count_, "hotness_count_");
@@ -782,9 +781,6 @@ class ArtMethod final {
/* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
- // Offset to the CodeItem.
- uint32_t dex_code_item_offset_;
-
// Index into method_ids of the dex file associated with this method.
uint32_t dex_method_index_;
@@ -816,7 +812,8 @@ class ArtMethod final {
// - conflict method: ImtConflictTable,
// - abstract/interface method: the single-implementation if any,
// - proxy method: the original interface method or constructor,
- // - other methods: the profiling data.
+ // - other methods: during AOT the code item offset, at runtime a pointer
+ // to the code item.
void* data_;
// Method dispatch from quick compiled code invokes this pointer which may cause bridging into
diff --git a/runtime/cha.cc b/runtime/cha.cc
index a142723e31..c345af8232 100644
--- a/runtime/cha.cc
+++ b/runtime/cha.cc
@@ -543,7 +543,8 @@ void ClassHierarchyAnalysis::InitSingleImplementationFlag(Handle<mirror::Class>
// Abstract method starts with single-implementation flag set and null
// implementation method.
method->SetHasSingleImplementation(true);
- DCHECK(method->GetSingleImplementation(pointer_size) == nullptr);
+ DCHECK(!method->HasCodeItem()) << method->PrettyMethod();
+ DCHECK(method->GetSingleImplementation(pointer_size) == nullptr) << method->PrettyMethod();
}
// Default conflicting methods cannot be treated with single implementations,
// as we need to call them (and not inline them) in case of ICCE.
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 09fa99b35a..c181c225aa 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2199,10 +2199,21 @@ bool ClassLinker::AddImageSpace(
}, space->Begin(), image_pointer_size_);
}
- if (interpreter::CanRuntimeUseNterp()) {
- // Set image methods' entry point that point to the interpreter bridge to the nterp entry point.
+ if (!runtime->IsAotCompiler()) {
+ bool can_use_nterp = interpreter::CanRuntimeUseNterp();
header.VisitPackedArtMethods([&](ArtMethod& method) REQUIRES_SHARED(Locks::mutator_lock_) {
- ChangeInterpreterBridgeToNterp(&method, this);
+ // In the image, the `data` pointer field of the ArtMethod contains the code
+ // item offset. Change this to the actual pointer to the code item.
+ if (method.HasCodeItem()) {
+ const dex::CodeItem* code_item = method.GetDexFile()->GetCodeItem(
+ reinterpret_cast32<uint32_t>(method.GetDataPtrSize(image_pointer_size_)));
+ method.SetDataPtrSize(code_item, image_pointer_size_);
+ }
+ // Set image methods' entry point that point to the interpreter bridge to the
+ // nterp entry point.
+ if (can_use_nterp) {
+ ChangeInterpreterBridgeToNterp(&method, this);
+ }
}, space->Begin(), image_pointer_size_);
}
@@ -3977,7 +3988,6 @@ void ClassLinker::LoadMethod(const DexFile& dex_file,
ScopedAssertNoThreadSuspension ants("LoadMethod");
dst->SetDexMethodIndex(dex_method_idx);
dst->SetDeclaringClass(klass.Get());
- dst->SetCodeItemOffset(method.GetCodeItemOffset());
// Get access flags from the DexFile and set hiddenapi runtime access flags.
uint32_t access_flags = method.GetAccessFlags() | hiddenapi::CreateRuntimeFlags(method);
@@ -4026,6 +4036,18 @@ void ClassLinker::LoadMethod(const DexFile& dex_file,
if (klass->IsInterface() && dst->IsAbstract()) {
dst->CalculateAndSetImtIndex();
}
+ if (dst->HasCodeItem()) {
+ DCHECK_NE(method.GetCodeItemOffset(), 0u);
+ if (Runtime::Current()->IsAotCompiler()) {
+ dst->SetDataPtrSize(reinterpret_cast32<void*>(method.GetCodeItemOffset()), image_pointer_size_);
+ } else {
+ dst->SetDataPtrSize(dst->GetDexFile()->GetCodeItem(method.GetCodeItemOffset()),
+ image_pointer_size_);
+ }
+ } else {
+ dst->SetDataPtrSize(nullptr, image_pointer_size_);
+ DCHECK_EQ(method.GetCodeItemOffset(), 0u);
+ }
}
void ClassLinker::AppendToBootClassPath(Thread* self, const DexFile* dex_file) {
@@ -5304,10 +5326,6 @@ void ClassLinker::CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prot
const uint32_t kAddFlags = kAccFinal | kAccCompileDontBother;
out->SetAccessFlags((out->GetAccessFlags() & ~kRemoveFlags) | kAddFlags);
- // Clear the dex_code_item_offset_. It needs to be 0 since proxy methods have no CodeItems but the
- // method they copy might (if it's a default method).
- out->SetCodeItemOffset(0);
-
// Set the original interface method.
out->SetDataPtrSize(prototype, image_pointer_size_);
diff --git a/runtime/dex/dex_file_annotations.cc b/runtime/dex/dex_file_annotations.cc
index 6261a93a5d..c149aeadf4 100644
--- a/runtime/dex/dex_file_annotations.cc
+++ b/runtime/dex/dex_file_annotations.cc
@@ -1745,7 +1745,7 @@ bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class>
int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t rel_pc) {
// For native method, lineno should be -2 to indicate it is native. Note that
// "line number == -2" is how libcore tells from StackTraceElement.
- if (method->GetCodeItemOffset() == 0) {
+ if (!method->HasCodeItem()) {
return -2;
}
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index e357b756c7..af63f68ca4 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -2872,8 +2872,10 @@ class ImageSpace::BootImageLoader {
image_header.VisitPackedArtMethods([&](ArtMethod& method)
REQUIRES_SHARED(Locks::mutator_lock_) {
main_patch_object_visitor.PatchGcRoot(&method.DeclaringClassRoot());
- void** data_address = PointerAddress(&method, ArtMethod::DataOffset(kPointerSize));
- main_patch_object_visitor.PatchNativePointer(data_address);
+ if (!method.HasCodeItem()) {
+ void** data_address = PointerAddress(&method, ArtMethod::DataOffset(kPointerSize));
+ main_patch_object_visitor.PatchNativePointer(data_address);
+ }
void** entrypoint_address =
PointerAddress(&method, ArtMethod::EntryPointFromQuickCompiledCodeOffset(kPointerSize));
main_patch_object_visitor.PatchNativePointer(entrypoint_address);
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index b5e52388b8..67644d66cd 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -445,7 +445,7 @@ void EnterInterpreterFromInvoke(Thread* self,
method->ThrowInvocationTimeError();
return;
} else {
- DCHECK(method->IsNative());
+ DCHECK(method->IsNative()) << method->PrettyMethod();
num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty());
if (!method->IsStatic()) {
num_regs++;
diff --git a/runtime/interpreter/mterp/arm64ng/main.S b/runtime/interpreter/mterp/arm64ng/main.S
index b4b3283a54..51ebea164b 100644
--- a/runtime/interpreter/mterp/arm64ng/main.S
+++ b/runtime/interpreter/mterp/arm64ng/main.S
@@ -645,13 +645,10 @@ END \name
ldp x0, x1, [sp], #16
.endm
+// Input: x0 contains the ArtMethod
// Output: x8 contains the code item
.macro GET_CODE_ITEM
- // TODO: Get code item in a better way.
- stp x0, x1, [sp, #-16]!
- bl NterpGetCodeItem
- mov x8, x0
- ldp x0, x1, [sp], #16
+ ldr x8, [x0, #ART_METHOD_DATA_OFFSET_64]
.endm
.macro DO_ENTRY_POINT_CHECK call_compiled_code
@@ -1498,11 +1495,9 @@ OAT_ENTRY ExecuteNterpImpl, EndExecuteNterpImpl
bl NterpGetShorty
// Save shorty in callee-save xIBASE.
mov xIBASE, x0
- mov x0, xINST
- bl NterpGetCodeItem
- mov xPC, x0
RESTORE_ALL_ARGUMENTS
+ ldr xPC, [xINST, #ART_METHOD_DATA_OFFSET_64]
// Setup the stack for executing the method.
SETUP_STACK_FRAME xPC, xREFS, xFP, CFI_REFS
diff --git a/runtime/interpreter/mterp/x86_64ng/main.S b/runtime/interpreter/mterp/x86_64ng/main.S
index 8966490602..cce72824e8 100644
--- a/runtime/interpreter/mterp/x86_64ng/main.S
+++ b/runtime/interpreter/mterp/x86_64ng/main.S
@@ -784,6 +784,9 @@ END_FUNCTION \name
// - rPC: the new PC pointer to execute
// - edi: number of arguments
// - ecx: first dex register
+//
+// This helper expects:
+// - rax to contain the code item
.macro SETUP_STACK_FOR_INVOKE
// We do the same stack overflow check as the compiler. See CanMethodUseNterp
// in how we limit the maximum nterp frame size.
@@ -969,13 +972,7 @@ END_FUNCTION \name
cmpq %rax, ART_METHOD_QUICK_CODE_OFFSET_64(%rdi)
jne VAR(call_compiled_code)
- // TODO: Get code item in a better way and remove below
- push %rdi
- push %rsi
- call SYMBOL(NterpGetCodeItem)
- pop %rsi
- pop %rdi
- // TODO: Get code item in a better way and remove above
+ movq ART_METHOD_DATA_OFFSET_64(%rdi), %rax
.endm
// Uses r9 and r10 as temporary
@@ -1389,9 +1386,6 @@ OAT_ENTRY ExecuteNterpImpl, EndExecuteNterpImpl
call SYMBOL(NterpGetShorty)
// Save shorty in callee-save rbp.
movq %rax, %rbp
- movq %rbx, %rdi
- call SYMBOL(NterpGetCodeItem)
- movq %rax, rPC
// Restore xmm registers + alignment.
movq 0(%rsp), %xmm0
@@ -1413,6 +1407,8 @@ OAT_ENTRY ExecuteNterpImpl, EndExecuteNterpImpl
POP rdi
// TODO: Get shorty in a better way and remove above
+ movq ART_METHOD_DATA_OFFSET_64(%rdi), rPC
+
// Setup the stack for executing the method.
SETUP_STACK_FRAME rPC, rREFS, rFP, CFI_REFS
diff --git a/tools/cpp-define-generator/art_method.def b/tools/cpp-define-generator/art_method.def
index 75fbab0c28..097d4662e1 100644
--- a/tools/cpp-define-generator/art_method.def
+++ b/tools/cpp-define-generator/art_method.def
@@ -28,6 +28,10 @@ ASM_DEFINE(ART_METHOD_JNI_OFFSET_32,
art::ArtMethod::EntryPointFromJniOffset(art::PointerSize::k32).Int32Value())
ASM_DEFINE(ART_METHOD_JNI_OFFSET_64,
art::ArtMethod::EntryPointFromJniOffset(art::PointerSize::k64).Int32Value())
+ASM_DEFINE(ART_METHOD_DATA_OFFSET_32,
+ art::ArtMethod::DataOffset(art::PointerSize::k32).Int32Value())
+ASM_DEFINE(ART_METHOD_DATA_OFFSET_64,
+ art::ArtMethod::DataOffset(art::PointerSize::k64).Int32Value())
ASM_DEFINE(ART_METHOD_QUICK_CODE_OFFSET_32,
art::ArtMethod::EntryPointFromQuickCompiledCodeOffset(art::PointerSize::k32).Int32Value())
ASM_DEFINE(ART_METHOD_QUICK_CODE_OFFSET_64,