summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2019-06-04 16:48:58 +0100
committer Nicolas Geoffray <ngeoffray@google.com> 2019-06-06 08:02:04 +0000
commitd2f13ba7153aa7b77e4662844233c848535f8aac (patch)
tree9a0f9bda0e886b1652cc306dba4a05648385beb0
parente7d7e9dd01b6ce5a079ebc7e369f4a8d4e42f7d8 (diff)
Remove requirement of a ProfilingInfo for jitted code.
When pre-jitting (zygote or system server in jit zygote mode), the profiling info is just memory overhead. Remove the need to have one. Bug: 119800099 Test: boot, testrunner.py --jit Change-Id: Ie74d870eebef72c903225542e9b41dfe98132419
-rw-r--r--compiler/optimizing/inliner.cc5
-rw-r--r--runtime/jit/jit.cc25
-rw-r--r--runtime/jit/jit.h2
-rw-r--r--runtime/jit/jit_code_cache.cc74
-rw-r--r--runtime/jit/jit_code_cache.h6
-rw-r--r--test/566-polymorphic-inlining/polymorphic_inline.cc2
-rw-r--r--test/570-checker-osr/osr.cc3
-rw-r--r--test/common/runtime_state.cc2
8 files changed, 47 insertions, 72 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 205077fb49..9ef5ec31d1 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -604,9 +604,8 @@ bool HInliner::TryInlineFromInlineCache(const DexFile& caller_dex_file,
switch (inline_cache_type) {
case kInlineCacheNoData: {
LOG_FAIL_NO_STAT()
- << "Interface or virtual call to "
- << caller_dex_file.PrettyMethod(invoke_instruction->GetDexMethodIndex())
- << " could not be statically determined";
+ << "No inline cache information for call to "
+ << caller_dex_file.PrettyMethod(invoke_instruction->GetDexMethodIndex());
return false;
}
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index b828aafcb0..68bdf53d12 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -246,7 +246,7 @@ bool Jit::LoadCompilerLibrary(std::string* error_msg) {
return true;
}
-bool Jit::CompileMethod(ArtMethod* method, Thread* self, bool baseline, bool osr) {
+bool Jit::CompileMethod(ArtMethod* method, Thread* self, bool baseline, bool osr, bool prejit) {
DCHECK(Runtime::Current()->UseJitCompilation());
DCHECK(!method->IsRuntimeMethod());
@@ -269,7 +269,7 @@ bool Jit::CompileMethod(ArtMethod* method, Thread* self, bool baseline, bool osr
// If we get a request to compile a proxy method, we pass the actual Java method
// of that proxy method, as the compiler does not expect a proxy method.
ArtMethod* method_to_compile = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
- if (!code_cache_->NotifyCompilationOf(method_to_compile, self, osr)) {
+ if (!code_cache_->NotifyCompilationOf(method_to_compile, self, osr, prejit)) {
return false;
}
@@ -561,6 +561,7 @@ class JitCompileTask final : public Task {
kCompile,
kCompileBaseline,
kCompileOsr,
+ kPreCompile,
};
JitCompileTask(ArtMethod* method, TaskKind kind) : method_(method), kind_(kind), klass_(nullptr) {
@@ -583,6 +584,7 @@ class JitCompileTask final : public Task {
void Run(Thread* self) override {
ScopedObjectAccess soa(self);
switch (kind_) {
+ case TaskKind::kPreCompile:
case TaskKind::kCompile:
case TaskKind::kCompileBaseline:
case TaskKind::kCompileOsr: {
@@ -590,7 +592,8 @@ class JitCompileTask final : public Task {
method_,
self,
/* baseline= */ (kind_ == TaskKind::kCompileBaseline),
- /* osr= */ (kind_ == TaskKind::kCompileOsr));
+ /* osr= */ (kind_ == TaskKind::kCompileOsr),
+ /* prejit= */ (kind_ == TaskKind::kPreCompile));
break;
}
case TaskKind::kAllocateProfile: {
@@ -796,19 +799,15 @@ void Jit::CompileMethodsFromProfile(
if (class_linker->IsQuickToInterpreterBridge(entry_point) ||
class_linker->IsQuickGenericJniStub(entry_point) ||
class_linker->IsQuickResolutionStub(entry_point)) {
- if (!method->IsNative()) {
- // The compiler requires a ProfilingInfo object for non-native methods.
- ProfilingInfo::Create(self, method, /* retry_allocation= */ true);
- }
// Special case ZygoteServer class so that it gets compiled before the
// zygote enters it. This avoids needing to do OSR during app startup.
// TODO: have a profile instead.
if (!add_to_queue || method->GetDeclaringClass()->DescriptorEquals(
"Lcom/android/internal/os/ZygoteServer;")) {
- CompileMethod(method, self, /* baseline= */ false, /* osr= */ false);
+ CompileMethod(method, self, /* baseline= */ false, /* osr= */ false, /* prejit= */ true);
} else {
thread_pool_->AddTask(self,
- new JitCompileTask(method, JitCompileTask::TaskKind::kCompile));
+ new JitCompileTask(method, JitCompileTask::TaskKind::kPreCompile));
}
}
}
@@ -890,7 +889,7 @@ bool Jit::MaybeCompileMethod(Thread* self,
method->IsNative() &&
Runtime::Current()->IsUsingApexBootImageLocation()) {
// jitzygote: Compile JNI stub on first use to avoid the expensive generic stub.
- CompileMethod(method, self, /* baseline= */ false, /* osr= */ false);
+ CompileMethod(method, self, /* baseline= */ false, /* osr= */ false, /* prejit= */ false);
return true;
}
if (old_count < HotMethodThreshold() && new_count >= HotMethodThreshold()) {
@@ -935,11 +934,7 @@ void Jit::MethodEntered(Thread* thread, ArtMethod* method) {
if (UNLIKELY(runtime->UseJitCompilation() && runtime->GetJit()->JitAtFirstUse())) {
ArtMethod* np_method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
if (np_method->IsCompilable()) {
- if (!np_method->IsNative()) {
- // The compiler requires a ProfilingInfo object for non-native methods.
- ProfilingInfo::Create(thread, np_method, /* retry_allocation= */ true);
- }
- JitCompileTask compile_task(method, JitCompileTask::TaskKind::kCompile);
+ JitCompileTask compile_task(method, JitCompileTask::TaskKind::kPreCompile);
// Fake being in a runtime thread so that class-load behavior will be the same as normal jit.
ScopedSetRuntimeThread ssrt(thread);
compile_task.Run(thread);
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index 4b81f717d5..92d2b55b4a 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -170,7 +170,7 @@ class Jit {
// Create JIT itself.
static Jit* Create(JitCodeCache* code_cache, JitOptions* options);
- bool CompileMethod(ArtMethod* method, Thread* self, bool baseline, bool osr)
+ bool CompileMethod(ArtMethod* method, Thread* self, bool baseline, bool osr, bool prejit)
REQUIRES_SHARED(Locks::mutator_lock_);
const JitCodeCache* GetCodeCache() const {
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 65e6d9d25f..2505111058 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -1127,12 +1127,15 @@ uint8_t* JitCodeCache::CommitCodeInternal(Thread* self,
// This situation currently only occurs in the jit-zygote mode.
DCHECK(Runtime::Current()->IsZygote());
DCHECK(Runtime::Current()->IsUsingApexBootImageLocation());
- DCHECK(method->GetProfilingInfo(kRuntimePointerSize) != nullptr);
DCHECK(method->GetDeclaringClass()->GetClassLoader() == nullptr);
- // Save the entrypoint, so it can be fethed later once the class is
- // initialized.
- method->GetProfilingInfo(kRuntimePointerSize)->SetSavedEntryPoint(
- method_header->GetEntryPoint());
+ // TODO(ngeoffray): In most cases, the zygote will not have a profiling
+ // info for a compiled method. Use a map instead.
+ if (method->GetProfilingInfo(kRuntimePointerSize) != nullptr) {
+ // Save the entrypoint, so it can be fetched later once the class is
+ // initialized.
+ method->GetProfilingInfo(kRuntimePointerSize)->SetSavedEntryPoint(
+ method_header->GetEntryPoint());
+ }
} else {
Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
method, method_header->GetEntryPoint());
@@ -1564,8 +1567,6 @@ void JitCodeCache::GarbageCollectCache(Thread* self) {
}
}
- DCHECK(CheckLiveCompiledCodeHasProfilingInfo());
-
// Change entry points of native methods back to the GenericJNI entrypoint.
for (const auto& entry : jni_stubs_map_) {
const JniStubData& data = entry.second;
@@ -1743,28 +1744,7 @@ void JitCodeCache::DoCollection(Thread* self, bool collect_profiling_info) {
return false;
});
profiling_infos_.erase(profiling_kept_end, profiling_infos_.end());
- DCHECK(CheckLiveCompiledCodeHasProfilingInfo());
- }
-}
-
-bool JitCodeCache::CheckLiveCompiledCodeHasProfilingInfo() {
- ScopedTrace trace(__FUNCTION__);
- // Check that methods we have compiled do have a ProfilingInfo object. We would
- // have memory leaks of compiled code otherwise.
- for (const auto& it : method_code_map_) {
- ArtMethod* method = it.second;
- if (method->GetProfilingInfo(kRuntimePointerSize) == nullptr) {
- const void* code_ptr = it.first;
- const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
- if (method_header->GetEntryPoint() == method->GetEntryPointFromQuickCompiledCode()) {
- // If the code is not dead, then we have a problem. Note that this can even
- // happen just after a collection, as mutator threads are running in parallel
- // and could deoptimize an existing compiled code.
- return false;
- }
- }
}
- return true;
}
OatQuickMethodHeader* JitCodeCache::LookupMethodHeader(uintptr_t pc, ArtMethod* method) {
@@ -2003,16 +1983,16 @@ bool JitCodeCache::IsOsrCompiled(ArtMethod* method) {
return osr_code_map_.find(method) != osr_code_map_.end();
}
-bool JitCodeCache::NotifyCompilationOf(ArtMethod* method, Thread* self, bool osr) {
+bool JitCodeCache::NotifyCompilationOf(ArtMethod* method, Thread* self, bool osr, bool prejit) {
if (!osr && ContainsPc(method->GetEntryPointFromQuickCompiledCode())) {
return false;
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
if (class_linker->IsQuickResolutionStub(method->GetEntryPointFromQuickCompiledCode())) {
- if (!Runtime::Current()->IsUsingApexBootImageLocation() || !Runtime::Current()->IsZygote()) {
- // Unless we're running as zygote in the jitzygote experiment, we currently don't save
- // the JIT compiled code if we cannot update the entrypoint due to having the resolution stub.
+ if (!prejit) {
+ // Unless we're pre-jitting, we currently don't save the JIT compiled code if we cannot
+ // update the entrypoint due to having the resolution stub.
VLOG(jit) << "Not compiling "
<< method->PrettyMethod()
<< " because it has the resolution stub";
@@ -2064,18 +2044,20 @@ bool JitCodeCache::NotifyCompilationOf(ArtMethod* method, Thread* self, bool osr
} else {
ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
if (info == nullptr) {
- VLOG(jit) << method->PrettyMethod() << " needs a ProfilingInfo to be compiled";
- // Because the counter is not atomic, there are some rare cases where we may not hit the
- // threshold for creating the ProfilingInfo. Reset the counter now to "correct" this.
- ClearMethodCounter(method, /*was_warm=*/ false);
- return false;
- }
-
- if (info->IsMethodBeingCompiled(osr)) {
- return false;
+ // When prejitting, we don't allocate a profiling info.
+ if (!prejit) {
+ VLOG(jit) << method->PrettyMethod() << " needs a ProfilingInfo to be compiled";
+ // Because the counter is not atomic, there are some rare cases where we may not hit the
+ // threshold for creating the ProfilingInfo. Reset the counter now to "correct" this.
+ ClearMethodCounter(method, /*was_warm=*/ false);
+ return false;
+ }
+ } else {
+ if (info->IsMethodBeingCompiled(osr)) {
+ return false;
+ }
+ info->SetIsMethodBeingCompiled(true, osr);
}
-
- info->SetIsMethodBeingCompiled(true, osr);
return true;
}
}
@@ -2113,8 +2095,10 @@ void JitCodeCache::DoneCompiling(ArtMethod* method, Thread* self, bool osr) {
} // else CommitCodeInternal() updated entrypoints of all methods in the JniStubData.
} else {
ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
- DCHECK(info->IsMethodBeingCompiled(osr));
- info->SetIsMethodBeingCompiled(false, osr);
+ if (info != nullptr) {
+ DCHECK(info->IsMethodBeingCompiled(osr));
+ info->SetIsMethodBeingCompiled(false, osr);
+ }
}
}
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index a3e10c75af..3078e2be8f 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -101,7 +101,7 @@ class JitCodeCache {
std::string* error_msg);
~JitCodeCache();
- bool NotifyCompilationOf(ArtMethod* method, Thread* self, bool osr)
+ bool NotifyCompilationOf(ArtMethod* method, Thread* self, bool osr, bool prejit)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!lock_);
@@ -381,10 +381,6 @@ class JitCodeCache {
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool CheckLiveCompiledCodeHasProfilingInfo()
- REQUIRES(lock_)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
CodeCacheBitmap* GetLiveBitmap() const {
return live_bitmap_.get();
}
diff --git a/test/566-polymorphic-inlining/polymorphic_inline.cc b/test/566-polymorphic-inlining/polymorphic_inline.cc
index 00827cf8d5..15187f3c59 100644
--- a/test/566-polymorphic-inlining/polymorphic_inline.cc
+++ b/test/566-polymorphic-inlining/polymorphic_inline.cc
@@ -46,7 +46,7 @@ static void do_checks(jclass cls, const char* method_name) {
usleep(1000);
}
// Will either ensure it's compiled or do the compilation itself.
- jit->CompileMethod(method, soa.Self(), /*baseline=*/ false, /*osr=*/ false);
+ jit->CompileMethod(method, soa.Self(), /*baseline=*/ false, /*osr=*/ false, /*prejit=*/ false);
}
CodeInfo info(header);
diff --git a/test/570-checker-osr/osr.cc b/test/570-checker-osr/osr.cc
index dc0e94cbc7..ee978c2675 100644
--- a/test/570-checker-osr/osr.cc
+++ b/test/570-checker-osr/osr.cc
@@ -128,7 +128,8 @@ extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasOsrCode(JNIEnv* env,
// Sleep to yield to the compiler thread.
usleep(1000);
// Will either ensure it's compiled or do the compilation itself.
- jit->CompileMethod(m, Thread::Current(), /*baseline=*/ false, /*osr=*/ true);
+ jit->CompileMethod(
+ m, Thread::Current(), /*baseline=*/ false, /*osr=*/ true, /*prejit=*/ false);
}
});
}
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index a0b2f1ea72..7b023dee6a 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -246,7 +246,7 @@ static void ForceJitCompiled(Thread* self, ArtMethod* method) REQUIRES(!Locks::m
ProfilingInfo::Create(self, method, /* retry_allocation */ true);
}
// Will either ensure it's compiled or do the compilation itself.
- jit->CompileMethod(method, self, /*baseline=*/ false, /*osr=*/ false);
+ jit->CompileMethod(method, self, /*baseline=*/ false, /*osr=*/ false, /*prejit=*/ false);
}
}
}