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
Change-Id: I622469a0cfa0e7082a2119f3d6a9491eb61e3f3d
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 2618661..81846df 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -49,6 +49,7 @@
#include "arch/x86_64/quick_method_frame_info_x86_64.h"
#include "arch/x86_64/registers_x86_64.h"
#include "art_field-inl.h"
+#include "art_method-inl.h"
#include "asm_support.h"
#include "atomic.h"
#include "base/arena_allocator.h"
@@ -73,7 +74,6 @@
#include "jni_internal.h"
#include "linear_alloc.h"
#include "mirror/array.h"
-#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "mirror/field.h"
@@ -189,6 +189,7 @@
is_native_bridge_loaded_(false),
zygote_max_failed_boots_(0) {
CheckAsmSupportOffsetsAndSizes();
+ std::fill(callee_save_methods_, callee_save_methods_ + arraysize(callee_save_methods_), 0u);
}
Runtime::~Runtime() {
@@ -425,20 +426,20 @@
ScopedObjectAccess soa(Thread::Current());
ClassLinker* cl = Runtime::Current()->GetClassLinker();
+ auto pointer_size = cl->GetImagePointerSize();
StackHandleScope<2> hs(soa.Self());
Handle<mirror::Class> class_loader_class(
hs.NewHandle(soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ClassLoader)));
CHECK(cl->EnsureInitialized(soa.Self(), class_loader_class, true, true));
- mirror::ArtMethod* getSystemClassLoader =
- class_loader_class->FindDirectMethod("getSystemClassLoader", "()Ljava/lang/ClassLoader;");
+ ArtMethod* getSystemClassLoader = class_loader_class->FindDirectMethod(
+ "getSystemClassLoader", "()Ljava/lang/ClassLoader;", pointer_size);
CHECK(getSystemClassLoader != nullptr);
JValue result = InvokeWithJValues(soa, nullptr, soa.EncodeMethod(getSystemClassLoader), nullptr);
JNIEnv* env = soa.Self()->GetJniEnv();
- ScopedLocalRef<jobject> system_class_loader(env,
- soa.AddLocalReference<jobject>(result.GetL()));
+ ScopedLocalRef<jobject> system_class_loader(env, soa.AddLocalReference<jobject>(result.GetL()));
CHECK(system_class_loader.get() != nullptr);
soa.Self()->SetClassLoaderOverride(system_class_loader.get());
@@ -867,18 +868,17 @@
}
jit_options_.reset(jit::JitOptions::CreateFromRuntimeArguments(runtime_options));
- bool use_jit = jit_options_->UseJIT();
if (IsAotCompiler()) {
// If we are already the compiler at this point, we must be dex2oat. Don't create the jit in
// this case.
// If runtime_options doesn't have UseJIT set to true then CreateFromRuntimeArguments returns
// null and we don't create the jit.
- use_jit = false;
+ jit_options_->SetUseJIT(false);
}
// Use MemMap arena pool for jit, malloc otherwise. Malloc arenas are faster to allocate but
// can't be trimmed as easily.
- const bool use_malloc = !use_jit;
+ const bool use_malloc = IsAotCompiler();
arena_pool_.reset(new ArenaPool(use_malloc, false));
if (IsCompiler() && Is64BitInstructionSet(kRuntimeISA)) {
// 4gb, no malloc. Explanation in header.
@@ -1089,6 +1089,7 @@
}
VLOG(startup) << "Runtime::Init exiting";
+
return true;
}
@@ -1311,7 +1312,6 @@
void Runtime::VisitConstantRoots(RootVisitor* visitor) {
// Visit the classes held as static in mirror classes, these can be visited concurrently and only
// need to be visited once per GC since they never change.
- mirror::ArtMethod::VisitRoots(visitor);
mirror::Class::VisitRoots(visitor);
mirror::Constructor::VisitRoots(visitor);
mirror::Reference::VisitRoots(visitor);
@@ -1350,17 +1350,9 @@
java_vm_->VisitRoots(visitor);
sentinel_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
pre_allocated_OutOfMemoryError_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
- resolution_method_.VisitRoot(visitor, RootInfo(kRootVMInternal));
pre_allocated_NoClassDefFoundError_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
- imt_conflict_method_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
- imt_unimplemented_method_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
- default_imt_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
- for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
- callee_save_methods_[i].VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
- }
verifier::MethodVerifier::VisitStaticRoots(visitor);
VisitTransactionRoots(visitor);
- instrumentation_.VisitRoots(visitor);
}
void Runtime::VisitNonConcurrentRoots(RootVisitor* visitor) {
@@ -1399,73 +1391,43 @@
}
}
-mirror::ObjectArray<mirror::ArtMethod>* Runtime::CreateDefaultImt(ClassLinker* cl) {
- Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
- Handle<mirror::ObjectArray<mirror::ArtMethod>> imtable(
- hs.NewHandle(cl->AllocArtMethodArray(self, 64)));
- mirror::ArtMethod* imt_conflict_method = Runtime::Current()->GetImtConflictMethod();
- for (size_t i = 0; i < static_cast<size_t>(imtable->GetLength()); i++) {
- imtable->Set<false>(i, imt_conflict_method);
- }
- return imtable.Get();
-}
-
-mirror::ArtMethod* Runtime::CreateImtConflictMethod() {
- Thread* self = Thread::Current();
- Runtime* runtime = Runtime::Current();
- ClassLinker* class_linker = runtime->GetClassLinker();
- StackHandleScope<1> hs(self);
- Handle<mirror::ArtMethod> method(hs.NewHandle(class_linker->AllocArtMethod(self)));
- method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod());
- // TODO: use a special method for imt conflict method saves.
- method->SetDexMethodIndex(DexFile::kDexNoIndex);
+ArtMethod* Runtime::CreateImtConflictMethod() {
+ auto* method = Runtime::Current()->GetClassLinker()->CreateRuntimeMethod();
// When compiling, the code pointer will get set later when the image is loaded.
- if (runtime->IsAotCompiler()) {
+ if (IsAotCompiler()) {
size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
method->SetEntryPointFromQuickCompiledCodePtrSize(nullptr, pointer_size);
} else {
method->SetEntryPointFromQuickCompiledCode(GetQuickImtConflictStub());
}
- return method.Get();
+ return method;
}
-void Runtime::SetImtConflictMethod(mirror::ArtMethod* method) {
- imt_conflict_method_ = GcRoot<mirror::ArtMethod>(method);
+void Runtime::SetImtConflictMethod(ArtMethod* method) {
+ CHECK(method != nullptr);
+ CHECK(method->IsRuntimeMethod());
+ imt_conflict_method_ = method;
}
-mirror::ArtMethod* Runtime::CreateResolutionMethod() {
- Thread* self = Thread::Current();
- Runtime* runtime = Runtime::Current();
- ClassLinker* class_linker = runtime->GetClassLinker();
- StackHandleScope<1> hs(self);
- Handle<mirror::ArtMethod> method(hs.NewHandle(class_linker->AllocArtMethod(self)));
- method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod());
- // TODO: use a special method for resolution method saves
- method->SetDexMethodIndex(DexFile::kDexNoIndex);
+ArtMethod* Runtime::CreateResolutionMethod() {
+ auto* method = Runtime::Current()->GetClassLinker()->CreateRuntimeMethod();
// When compiling, the code pointer will get set later when the image is loaded.
- if (runtime->IsAotCompiler()) {
+ if (IsAotCompiler()) {
size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
method->SetEntryPointFromQuickCompiledCodePtrSize(nullptr, pointer_size);
} else {
method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionStub());
}
- return method.Get();
+ return method;
}
-mirror::ArtMethod* Runtime::CreateCalleeSaveMethod() {
- Thread* self = Thread::Current();
- Runtime* runtime = Runtime::Current();
- ClassLinker* class_linker = runtime->GetClassLinker();
- StackHandleScope<1> hs(self);
- Handle<mirror::ArtMethod> method(hs.NewHandle(class_linker->AllocArtMethod(self)));
- method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod());
- // TODO: use a special method for callee saves
- method->SetDexMethodIndex(DexFile::kDexNoIndex);
+ArtMethod* Runtime::CreateCalleeSaveMethod() {
+ auto* method = Runtime::Current()->GetClassLinker()->CreateRuntimeMethod();
size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
method->SetEntryPointFromQuickCompiledCodePtrSize(nullptr, pointer_size);
DCHECK_NE(instruction_set_, kNone);
- return method.Get();
+ DCHECK(method->IsRuntimeMethod());
+ return method;
}
void Runtime::DisallowNewSystemWeaks() {
@@ -1525,15 +1487,16 @@
}
}
-void Runtime::SetCalleeSaveMethod(mirror::ArtMethod* method, CalleeSaveType type) {
+void Runtime::SetCalleeSaveMethod(ArtMethod* method, CalleeSaveType type) {
DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType));
- callee_save_methods_[type] = GcRoot<mirror::ArtMethod>(method);
+ CHECK(method != nullptr);
+ callee_save_methods_[type] = reinterpret_cast<uintptr_t>(method);
}
void Runtime::StartProfiler(const char* profile_output_filename) {
profile_output_filename_ = profile_output_filename;
profiler_started_ =
- BackgroundMethodSamplingProfiler::Start(profile_output_filename_, profiler_options_);
+ BackgroundMethodSamplingProfiler::Start(profile_output_filename_, profiler_options_);
}
// Transaction support.
@@ -1550,7 +1513,6 @@
preinitialization_transaction_ = nullptr;
}
-
bool Runtime::IsTransactionAborted() const {
if (!IsActiveTransaction()) {
return false;
@@ -1709,4 +1671,16 @@
return IsCompiler() && compiler_callbacks_->IsBootImage();
}
+void Runtime::SetResolutionMethod(ArtMethod* method) {
+ CHECK(method != nullptr);
+ CHECK(method->IsRuntimeMethod()) << method;
+ resolution_method_ = method;
+}
+
+void Runtime::SetImtUnimplementedMethod(ArtMethod* method) {
+ CHECK(method != nullptr);
+ CHECK(method->IsRuntimeMethod());
+ imt_unimplemented_method_ = method;
+}
+
} // namespace art