DO NOT MERGE. Only have a portable entrypoint in portable builds.
Bug: 16214885
Change-Id: Iff7b7415efdbdabd7e6020e221a540f6a774c852
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 1823366..1e6c038 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -217,8 +217,11 @@
// No code? You must mean to go into the interpreter.
// Or the generic JNI...
if (!method->IsNative()) {
- const void* method_code = kUsePortableCompiler ? GetPortableToInterpreterBridge()
- : GetQuickToInterpreterBridge();
+#if defined(ART_USE_PORTABLE_COMPILER)
+ const void* method_code = GetPortableToInterpreterBridge();
+#else
+ const void* method_code = GetQuickToInterpreterBridge();
+#endif
OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
oat_method.LinkMethod(method);
method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
@@ -231,6 +234,7 @@
}
}
// Create bridges to transition between different kinds of compiled bridge.
+#if defined(ART_USE_PORTABLE_COMPILER)
if (method->GetEntryPointFromPortableCompiledCode() == nullptr) {
method->SetEntryPointFromPortableCompiledCode(GetPortableToQuickBridge());
} else {
@@ -238,6 +242,9 @@
method->SetEntryPointFromQuickCompiledCode(GetQuickToPortableBridge());
method->SetIsPortableCompiled();
}
+#else
+ CHECK(method->GetEntryPointFromQuickCompiledCode() != nullptr);
+#endif
}
void CommonCompilerTest::MakeExecutable(const void* code_start, size_t code_length) {
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 9ae9bd4..9ba6645 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -129,10 +129,12 @@
<< " "
<< dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
<< " " << dex->GetMethodName(dex->GetMethodId(i));
+#if defined(ART_USE_PORTABLE_COMPILER)
EXPECT_TRUE(method->GetEntryPointFromPortableCompiledCode() != NULL) << "method_idx=" << i
<< " "
<< dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
<< " " << dex->GetMethodName(dex->GetMethodId(i));
+#endif
}
EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index ba7e13f..c6fc115 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -739,17 +739,23 @@
// The resolution method has a special trampoline to call.
if (UNLIKELY(orig == Runtime::Current()->GetResolutionMethod())) {
+#if defined(ART_USE_PORTABLE_COMPILER)
copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_resolution_trampoline_offset_));
+#endif
copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_resolution_trampoline_offset_));
} else if (UNLIKELY(orig == Runtime::Current()->GetImtConflictMethod())) {
+#if defined(ART_USE_PORTABLE_COMPILER)
copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_imt_conflict_trampoline_offset_));
+#endif
copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_imt_conflict_trampoline_offset_));
} else {
// We assume all methods have code. If they don't currently then we set them to the use the
// resolution trampoline. Abstract methods never have code and so we need to make sure their
// use results in an AbstractMethodError. We use the interpreter to achieve this.
if (UNLIKELY(orig->IsAbstract())) {
+#if defined(ART_USE_PORTABLE_COMPILER)
copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_to_interpreter_bridge_offset_));
+#endif
copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_to_interpreter_bridge_offset_));
copy->SetEntryPointFromInterpreter<kVerifyNone>(reinterpret_cast<EntryPointFromInterpreter*>
(const_cast<byte*>(GetOatAddress(interpreter_to_interpreter_bridge_offset_))));
@@ -759,8 +765,9 @@
copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(quick_code);
// Portable entrypoint:
- const byte* portable_code = GetOatAddress(orig->GetPortableOatCodeOffset());
bool portable_is_interpreted = false;
+#if defined(ART_USE_PORTABLE_COMPILER)
+ const byte* portable_code = GetOatAddress(orig->GetPortableOatCodeOffset());
if (portable_code != nullptr &&
(!orig->IsStatic() || orig->IsConstructor() || orig->GetDeclaringClass()->IsInitialized())) {
// We have code for a non-static or initialized method, just use the code.
@@ -780,7 +787,7 @@
portable_code = GetOatAddress(portable_resolution_trampoline_offset_);
}
copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(portable_code);
-
+#endif
// JNI entrypoint:
if (orig->IsNative()) {
// The native method's pointer is set to a stub to lookup via dlsym.
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 4626f38..ed1175b 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -80,8 +80,10 @@
CompileMethod(method);
ASSERT_TRUE(method->GetEntryPointFromQuickCompiledCode() != nullptr)
<< method_name << " " << method_sig;
+#if defined(ART_USE_PORTABLE_COMPILER)
ASSERT_TRUE(method->GetEntryPointFromPortableCompiledCode() != nullptr)
<< method_name << " " << method_sig;
+#endif
}
}
}
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index 7403660..b07b57b 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -410,11 +410,13 @@
void PatchOat::FixupMethod(mirror::ArtMethod* object, mirror::ArtMethod* copy) {
// Just update the entry points if it looks like we should.
// TODO: sanity check all the pointers' values
+#if defined(ART_USE_PORTABLE_COMPILER)
uintptr_t portable = reinterpret_cast<uintptr_t>(
object->GetEntryPointFromPortableCompiledCode<kVerifyNone>());
if (portable != 0) {
copy->SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(portable + delta_));
}
+#endif
uintptr_t quick= reinterpret_cast<uintptr_t>(
object->GetEntryPointFromQuickCompiledCode<kVerifyNone>());
if (quick != 0) {
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index 62f3593..5978443 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -27,7 +27,7 @@
#define CLASS_OFFSET 0
#define LOCK_WORD_OFFSET 4
-#ifndef USE_BAKER_OR_BROOKS_READ_BARRIER
+#if !defined(USE_BAKER_OR_BROOKS_READ_BARRIER)
// Offsets within java.lang.Class.
#define CLASS_COMPONENT_TYPE_OFFSET 12
@@ -44,8 +44,13 @@
// Offsets within java.lang.Method.
#define METHOD_DEX_CACHE_METHODS_OFFSET 12
+#if defined(ART_USE_PORTABLE_COMPILER)
#define METHOD_PORTABLE_CODE_OFFSET 40
#define METHOD_QUICK_CODE_OFFSET 48
+#else
+#define METHOD_PORTABLE_CODE_OFFSET 40
+#define METHOD_QUICK_CODE_OFFSET 40
+#endif // ART_USE_PORTABLE_COMPILER
#else
@@ -67,6 +72,6 @@
#define METHOD_PORTABLE_CODE_OFFSET 48
#define METHOD_QUICK_CODE_OFFSET 56
-#endif
+#endif // USE_BAKER_OR_BROOKS_READ_BARRIER
#endif // ART_RUNTIME_ASM_SUPPORT_H_
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 95a2e63..bb0c41a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1570,7 +1570,9 @@
method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
if (method != Runtime::Current()->GetResolutionMethod()) {
method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(GetPortableToInterpreterBridge());
+#endif
}
}
}
@@ -2416,9 +2418,11 @@
if (method->IsNative()) {
// No code and native? Use generic trampoline.
result = GetQuickGenericJniTrampoline();
+#if defined(ART_USE_PORTABLE_COMPILER)
} else if (method->IsPortableCompiled()) {
// No code? Do we expect portable code?
result = GetQuickToPortableBridge();
+#endif
} else {
// No code? You must mean to go into the interpreter.
result = GetQuickToInterpreterBridge();
@@ -2427,6 +2431,7 @@
return result;
}
+#if defined(ART_USE_PORTABLE_COMPILER)
const void* ClassLinker::GetPortableOatCodeFor(mirror::ArtMethod* method,
bool* have_portable_code) {
CHECK(!method->IsAbstract()) << PrettyMethod(method);
@@ -2455,6 +2460,7 @@
}
return result;
}
+#endif
const void* ClassLinker::GetQuickOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx,
uint32_t method_idx) {
@@ -2466,6 +2472,7 @@
return oat_class.GetOatMethod(oat_method_idx).GetQuickCode();
}
+#if defined(ART_USE_PORTABLE_COMPILER)
const void* ClassLinker::GetPortableOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx,
uint32_t method_idx) {
OatFile::OatClass oat_class;
@@ -2475,6 +2482,7 @@
uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, class_def_idx, method_idx);
return oat_class.GetOatMethod(oat_method_idx).GetPortableCode();
}
+#endif
// Returns true if the method must run with interpreter, false otherwise.
static bool NeedsInterpreter(
@@ -2548,12 +2556,17 @@
// Check whether the method is native, in which case it's generic JNI.
if (quick_code == nullptr && portable_code == nullptr && method->IsNative()) {
quick_code = GetQuickGenericJniTrampoline();
+#if defined(ART_USE_PORTABLE_COMPILER)
portable_code = GetPortableToQuickBridge();
+#endif
} else {
+#if defined(ART_USE_PORTABLE_COMPILER)
portable_code = GetPortableToInterpreterBridge();
+#endif
quick_code = GetQuickToInterpreterBridge();
}
} else {
+#if defined(ART_USE_PORTABLE_COMPILER)
if (portable_code == nullptr) {
portable_code = GetPortableToQuickBridge();
} else {
@@ -2562,6 +2575,11 @@
if (quick_code == nullptr) {
quick_code = GetQuickToPortableBridge();
}
+#else
+ if (quick_code == nullptr) {
+ quick_code = GetQuickToInterpreterBridge();
+ }
+#endif
}
runtime->GetInstrumentation()->UpdateMethodsCode(method, quick_code, portable_code,
have_portable_code);
@@ -2578,7 +2596,9 @@
}
// Method shouldn't have already been linked.
DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
+#if defined(ART_USE_PORTABLE_COMPILER)
DCHECK(method->GetEntryPointFromPortableCompiledCode() == nullptr);
+#endif
if (oat_class != nullptr) {
// Every kind of method should at least get an invoke stub from the oat_method.
// non-abstract methods also get their code pointers.
@@ -2589,7 +2609,11 @@
// Install entry point from interpreter.
bool enter_interpreter = NeedsInterpreter(method.Get(),
method->GetEntryPointFromQuickCompiledCode(),
+#if defined(ART_USE_PORTABLE_COMPILER)
method->GetEntryPointFromPortableCompiledCode());
+#else
+ nullptr);
+#endif
if (enter_interpreter && !method->IsNative()) {
method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
} else {
@@ -2598,7 +2622,9 @@
if (method->IsAbstract()) {
method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(GetPortableToInterpreterBridge());
+#endif
return;
}
@@ -2608,23 +2634,33 @@
// It will be replaced by the proper entry point by ClassLinker::FixupStaticTrampolines
// after initializing class (see ClassLinker::InitializeClass method).
method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionTrampoline());
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(GetPortableResolutionTrampoline());
+#endif
} else if (enter_interpreter) {
if (!method->IsNative()) {
// Set entry point from compiled code if there's no code or in interpreter only mode.
method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(GetPortableToInterpreterBridge());
+#endif
} else {
method->SetEntryPointFromQuickCompiledCode(GetQuickGenericJniTrampoline());
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(GetPortableToQuickBridge());
+#endif
}
+#if defined(ART_USE_PORTABLE_COMPILER)
} else if (method->GetEntryPointFromPortableCompiledCode() != nullptr) {
DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
have_portable_code = true;
method->SetEntryPointFromQuickCompiledCode(GetQuickToPortableBridge());
+#endif
} else {
DCHECK(method->GetEntryPointFromQuickCompiledCode() != nullptr);
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(GetPortableToQuickBridge());
+#endif
}
if (method->IsNative()) {
@@ -2643,7 +2679,11 @@
Runtime* runtime = Runtime::Current();
runtime->GetInstrumentation()->UpdateMethodsCode(method.Get(),
method->GetEntryPointFromQuickCompiledCode(),
+#if defined(ART_USE_PORTABLE_COMPILER)
method->GetEntryPointFromPortableCompiledCode(),
+#else
+ nullptr,
+#endif
have_portable_code);
}
@@ -3924,7 +3964,9 @@
// At runtime the method looks like a reference and argument saving method, clone the code
// related parameters from this method.
method->SetEntryPointFromQuickCompiledCode(GetQuickProxyInvokeHandler());
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(GetPortableProxyInvokeHandler());
+#endif
method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
return method;
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 2203628..107a4b2 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -342,14 +342,18 @@
// Get the oat code for a method when its class isn't yet initialized
const void* GetQuickOatCodeFor(mirror::ArtMethod* method)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#if defined(ART_USE_PORTABLE_COMPILER)
const void* GetPortableOatCodeFor(mirror::ArtMethod* method, bool* have_portable_code)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#endif
// Get the oat code for a method from a method index.
const void* GetQuickOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx, uint32_t method_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#if defined(ART_USE_PORTABLE_COMPILER)
const void* GetPortableOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx, uint32_t method_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#endif
pid_t GetClassesLockOwner(); // For SignalCatcher.
pid_t GetDexLockOwner(); // For SignalCatcher.
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 883c6e2..37564e8 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -488,7 +488,9 @@
// alphabetical 64-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, entry_point_from_interpreter_), "entryPointFromInterpreter"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, entry_point_from_jni_), "entryPointFromJni"));
+#if defined(ART_USE_PORTABLE_COMPILER)
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, entry_point_from_portable_compiled_code_), "entryPointFromPortableCompiledCode"));
+#endif
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, entry_point_from_quick_compiled_code_), "entryPointFromQuickCompiledCode"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, gc_map_), "gcMap"));
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 44c89ad..bc95c23 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -199,6 +199,7 @@
return reinterpret_cast<uintptr_t>(art_quick_instrumentation_exit);
}
+#if defined(ART_USE_PORTABLE_COMPILER)
extern "C" void art_portable_to_interpreter_bridge(mirror::ArtMethod*);
static inline const void* GetPortableToInterpreterBridge() {
return reinterpret_cast<void*>(art_portable_to_interpreter_bridge);
@@ -208,12 +209,14 @@
// TODO: portable to quick bridge. Bug: 8196384
return GetPortableToInterpreterBridge();
}
+#endif
extern "C" void art_quick_to_interpreter_bridge(mirror::ArtMethod*);
static inline const void* GetQuickToInterpreterBridge() {
return reinterpret_cast<void*>(art_quick_to_interpreter_bridge);
}
+#if defined(ART_USE_PORTABLE_COMPILER)
static inline const void* GetQuickToPortableBridge() {
// TODO: quick to portable bridge. Bug: 8196384
return GetQuickToInterpreterBridge();
@@ -223,6 +226,7 @@
static inline const void* GetPortableProxyInvokeHandler() {
return reinterpret_cast<void*>(art_portable_proxy_invoke_handler);
}
+#endif
extern "C" void art_quick_proxy_invoke_handler();
static inline const void* GetQuickProxyInvokeHandler() {
diff --git a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
index 6f9c083..16ce471 100644
--- a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
@@ -37,7 +37,11 @@
}
}
DCHECK(!self->IsExceptionPending());
+#if defined(ART_USE_PORTABLE_COMPILER)
const void* code = method->GetEntryPointFromPortableCompiledCode();
+#else
+ const void* code = nullptr;
+#endif
// When we return, the caller will branch to this address, so it had better not be 0!
if (UNLIKELY(code == NULL)) {
diff --git a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
index 9f75b0f..f90288b 100644
--- a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
@@ -401,25 +401,39 @@
Handle<mirror::Class> called_class(hs.NewHandle(called->GetDeclaringClass()));
linker->EnsureInitialized(called_class, true, true);
if (LIKELY(called_class->IsInitialized())) {
+#if defined(ART_USE_PORTABLE_COMPILER)
code = called->GetEntryPointFromPortableCompiledCode();
+#else
+ code = nullptr;
+#endif
// TODO: remove this after we solve the link issue.
if (code == nullptr) {
+#if defined(ART_USE_PORTABLE_COMPILER)
bool have_portable_code;
code = linker->GetPortableOatCodeFor(called, &have_portable_code);
+#endif
}
} else if (called_class->IsInitializing()) {
if (invoke_type == kStatic) {
// Class is still initializing, go to oat and grab code (trampoline must be left in place
// until class is initialized to stop races between threads).
+#if defined(ART_USE_PORTABLE_COMPILER)
bool have_portable_code;
code = linker->GetPortableOatCodeFor(called, &have_portable_code);
+#endif
} else {
// No trampoline for non-static methods.
+#if defined(ART_USE_PORTABLE_COMPILER)
code = called->GetEntryPointFromPortableCompiledCode();
+#else
+ code = nullptr;
+#endif
// TODO: remove this after we solve the link issue.
if (code == nullptr) {
+#if defined(ART_USE_PORTABLE_COMPILER)
bool have_portable_code;
code = linker->GetPortableOatCodeFor(called, &have_portable_code);
+#endif
}
}
} else {
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index a2e88a6..88a57f2 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -85,7 +85,9 @@
static void UpdateEntrypoints(mirror::ArtMethod* method, const void* quick_code,
const void* portable_code, bool have_portable_code)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(portable_code);
+#endif
method->SetEntryPointFromQuickCompiledCode(quick_code);
bool portable_enabled = method->IsPortableCompiled();
if (have_portable_code && !portable_enabled) {
@@ -102,9 +104,13 @@
&& !method->IsNative() && !method->IsProxyMethod())) {
if (kIsDebugBuild) {
if (quick_code == GetQuickToInterpreterBridge()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
DCHECK(portable_code == GetPortableToInterpreterBridge());
+#endif
} else if (quick_code == class_linker->GetQuickResolutionTrampoline()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
DCHECK(portable_code == class_linker->GetPortableResolutionTrampoline());
+#endif
}
}
DCHECK(!method->IsNative()) << PrettyMethod(method);
@@ -132,21 +138,32 @@
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
bool is_class_initialized = method->GetDeclaringClass()->IsInitialized();
bool have_portable_code = false;
+#if !defined(ART_USE_PORTABLE_COMPILER)
+ new_portable_code = nullptr;
+#endif
if (uninstall) {
if ((forced_interpret_only_ || IsDeoptimized(method)) && !method->IsNative()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = GetPortableToInterpreterBridge();
+#endif
new_quick_code = GetQuickToInterpreterBridge();
} else if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = class_linker->GetPortableOatCodeFor(method, &have_portable_code);
+#endif
new_quick_code = class_linker->GetQuickOatCodeFor(method);
} else {
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = class_linker->GetPortableResolutionTrampoline();
+#endif
new_quick_code = class_linker->GetQuickResolutionTrampoline();
}
} else { // !uninstall
if ((interpreter_stubs_installed_ || forced_interpret_only_ || IsDeoptimized(method)) &&
!method->IsNative()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = GetPortableToInterpreterBridge();
+#endif
new_quick_code = GetQuickToInterpreterBridge();
} else {
// Do not overwrite resolution trampoline. When the trampoline initializes the method's
@@ -154,15 +171,21 @@
// For more details, see ClassLinker::FixupStaticTrampolines.
if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
if (entry_exit_stubs_installed_) {
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = GetPortableToInterpreterBridge();
+#endif
new_quick_code = GetQuickInstrumentationEntryPoint();
} else {
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = class_linker->GetPortableOatCodeFor(method, &have_portable_code);
+#endif
new_quick_code = class_linker->GetQuickOatCodeFor(method);
DCHECK(new_quick_code != class_linker->GetQuickToInterpreterBridgeTrampoline());
}
} else {
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = class_linker->GetPortableResolutionTrampoline();
+#endif
new_quick_code = class_linker->GetQuickResolutionTrampoline();
}
}
@@ -657,7 +680,11 @@
new_have_portable_code = have_portable_code;
} else {
if ((interpreter_stubs_installed_ || IsDeoptimized(method)) && !method->IsNative()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = GetPortableToInterpreterBridge();
+#else
+ new_portable_code = portable_code;
+#endif
new_quick_code = GetQuickToInterpreterBridge();
new_have_portable_code = false;
} else {
@@ -665,14 +692,20 @@
if (quick_code == class_linker->GetQuickResolutionTrampoline() ||
quick_code == class_linker->GetQuickToInterpreterBridgeTrampoline() ||
quick_code == GetQuickToInterpreterBridge()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
DCHECK((portable_code == class_linker->GetPortableResolutionTrampoline()) ||
(portable_code == GetPortableToInterpreterBridge()));
+#endif
new_portable_code = portable_code;
new_quick_code = quick_code;
new_have_portable_code = have_portable_code;
} else if (entry_exit_stubs_installed_) {
new_quick_code = GetQuickInstrumentationEntryPoint();
+#if defined(ART_USE_PORTABLE_COMPILER)
new_portable_code = GetPortableToInterpreterBridge();
+#else
+ new_portable_code = portable_code;
+#endif
new_have_portable_code = false;
} else {
new_portable_code = portable_code;
@@ -754,7 +787,12 @@
<< " is already deoptimized";
}
if (!interpreter_stubs_installed_) {
- UpdateEntrypoints(method, GetQuickInstrumentationEntryPoint(), GetPortableToInterpreterBridge(),
+ UpdateEntrypoints(method, GetQuickInstrumentationEntryPoint(),
+#if defined(ART_USE_PORTABLE_COMPILER)
+ GetPortableToInterpreterBridge(),
+#else
+ nullptr,
+#endif
false);
// Install instrumentation exit stub and instrumentation frames. We may already have installed
@@ -788,11 +826,20 @@
!method->GetDeclaringClass()->IsInitialized()) {
// TODO: we're updating to entrypoints in the image here, we can avoid the trampoline.
UpdateEntrypoints(method, class_linker->GetQuickResolutionTrampoline(),
- class_linker->GetPortableResolutionTrampoline(), false);
+#if defined(ART_USE_PORTABLE_COMPILER)
+ class_linker->GetPortableResolutionTrampoline(),
+#else
+ nullptr,
+#endif
+ false);
} else {
bool have_portable_code = false;
const void* quick_code = class_linker->GetQuickOatCodeFor(method);
+#if defined(ART_USE_PORTABLE_COMPILER)
const void* portable_code = class_linker->GetPortableOatCodeFor(method, &have_portable_code);
+#else
+ const void* portable_code = nullptr;
+#endif
UpdateEntrypoints(method, quick_code, portable_code, have_portable_code);
}
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index fbbe1b6..9782dde 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -207,20 +207,25 @@
return PointerToLowMemUInt32(GetEntryPointFromQuickCompiledCode());
}
+
+#if defined(ART_USE_PORTABLE_COMPILER)
inline uint32_t ArtMethod::GetPortableOatCodeOffset() {
DCHECK(!Runtime::Current()->IsStarted());
return PointerToLowMemUInt32(GetEntryPointFromPortableCompiledCode());
}
+#endif
inline void ArtMethod::SetQuickOatCodeOffset(uint32_t code_offset) {
DCHECK(!Runtime::Current()->IsStarted());
SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(code_offset));
}
+#if defined(ART_USE_PORTABLE_COMPILER)
inline void ArtMethod::SetPortableOatCodeOffset(uint32_t code_offset) {
DCHECK(!Runtime::Current()->IsStarted());
SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(code_offset));
}
+#endif
inline const void* ArtMethod::GetQuickOatEntryPoint() {
if (IsPortableCompiled() || IsAbstract() || IsRuntimeMethod() || IsProxyMethod()) {
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index 370bfb9..27499c2 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -310,13 +310,21 @@
} else {
const bool kLogInvocationStartAndReturn = false;
bool have_quick_code = GetEntryPointFromQuickCompiledCode() != nullptr;
+#if defined(ART_USE_PORTABLE_COMPILER)
bool have_portable_code = GetEntryPointFromPortableCompiledCode() != nullptr;
+#else
+ bool have_portable_code = false;
+#endif
if (LIKELY(have_quick_code || have_portable_code)) {
if (kLogInvocationStartAndReturn) {
LOG(INFO) << StringPrintf("Invoking '%s' %s code=%p", PrettyMethod(this).c_str(),
have_quick_code ? "quick" : "portable",
have_quick_code ? GetEntryPointFromQuickCompiledCode()
+#if defined(ART_USE_PORTABLE_COMPILER)
: GetEntryPointFromPortableCompiledCode());
+#else
+ : nullptr);
+#endif
}
if (!IsPortableCompiled()) {
#ifdef __LP64__
@@ -345,7 +353,11 @@
LOG(INFO) << StringPrintf("Returned '%s' %s code=%p", PrettyMethod(this).c_str(),
have_quick_code ? "quick" : "portable",
have_quick_code ? GetEntryPointFromQuickCompiledCode()
+#if defined(ART_USE_PORTABLE_COMPILER)
: GetEntryPointFromPortableCompiledCode());
+#else
+ : nullptr);
+#endif
}
} else {
LOG(INFO) << "Not invoking '" << PrettyMethod(this) << "' code=null";
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index fa592c2..abfdd42 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -151,7 +151,7 @@
}
bool IsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return (GetAccessFlags() & kAccPortableCompiled) != 0;
+ return kUsePortableCompiler && ((GetAccessFlags() & kAccPortableCompiled) != 0);
}
void SetIsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -257,6 +257,7 @@
entry_point_from_interpreter);
}
+#if defined(ART_USE_PORTABLE_COMPILER)
static MemberOffset EntryPointFromPortableCompiledCodeOffset() {
return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_portable_compiled_code_));
}
@@ -273,6 +274,7 @@
SetFieldPtr<false, true, kVerifyFlags>(
EntryPointFromPortableCompiledCodeOffset(), entry_point_from_portable_compiled_code);
}
+#endif
static MemberOffset EntryPointFromQuickCompiledCodeOffset() {
return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_quick_compiled_code_));
@@ -309,10 +311,12 @@
void AssertPcIsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uint32_t GetQuickOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#if defined(ART_USE_PORTABLE_COMPILER)
uint32_t GetPortableOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetQuickOatCodeOffset(uint32_t code_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetPortableOatCodeOffset(uint32_t code_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#endif
+ uint32_t GetQuickOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetQuickOatCodeOffset(uint32_t code_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static const void* EntryPointToCodePointer(const void* entry_point) ALWAYS_INLINE {
uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
@@ -498,7 +502,9 @@
// Method dispatch from portable compiled code invokes this pointer which may cause bridging into
// quick compiled code or the interpreter.
+#if defined(ART_USE_PORTABLE_COMPILER)
uint64_t entry_point_from_portable_compiled_code_;
+#endif
// Method dispatch from quick compiled code invokes this pointer which may cause bridging into
// portable compiled code or the interpreter.
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index bc872e6..ede3b64 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -90,7 +90,9 @@
EXPECT_EQ(STRING_DATA_OFFSET, Array::DataOffset(sizeof(uint16_t)).Int32Value());
EXPECT_EQ(METHOD_DEX_CACHE_METHODS_OFFSET, ArtMethod::DexCacheResolvedMethodsOffset().Int32Value());
+#if defined(ART_USE_PORTABLE_COMPILER)
EXPECT_EQ(METHOD_PORTABLE_CODE_OFFSET, ArtMethod::EntryPointFromPortableCompiledCodeOffset().Int32Value());
+#endif
EXPECT_EQ(METHOD_QUICK_CODE_OFFSET, ArtMethod::EntryPointFromQuickCompiledCodeOffset().Int32Value());
}
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 1fdca2f..025f87d 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -592,9 +592,11 @@
void OatFile::OatMethod::LinkMethod(mirror::ArtMethod* method) const {
CHECK(method != NULL);
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(GetPortableCode());
+#endif
method->SetEntryPointFromQuickCompiledCode(GetQuickCode());
- method->SetNativeGcMap(GetNativeGcMap()); // Used by native methods in work around JNI mode.
+ method->SetNativeGcMap(GetNativeGcMap());
}
} // namespace art
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 60d641e..c76390b 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1192,10 +1192,14 @@
method->SetDexMethodIndex(DexFile::kDexNoIndex);
// When compiling, the code pointer will get set later when the image is loaded.
if (runtime->IsCompiler()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(nullptr);
+#endif
method->SetEntryPointFromQuickCompiledCode(nullptr);
} else {
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(class_linker->GetPortableImtConflictTrampoline());
+#endif
method->SetEntryPointFromQuickCompiledCode(class_linker->GetQuickImtConflictTrampoline());
}
return method.Get();
@@ -1212,10 +1216,14 @@
method->SetDexMethodIndex(DexFile::kDexNoIndex);
// When compiling, the code pointer will get set later when the image is loaded.
if (runtime->IsCompiler()) {
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(nullptr);
+#endif
method->SetEntryPointFromQuickCompiledCode(nullptr);
} else {
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(class_linker->GetPortableResolutionTrampoline());
+#endif
method->SetEntryPointFromQuickCompiledCode(class_linker->GetQuickResolutionTrampoline());
}
return method.Get();
@@ -1230,7 +1238,9 @@
method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod());
// TODO: use a special method for callee saves
method->SetDexMethodIndex(DexFile::kDexNoIndex);
+#if defined(ART_USE_PORTABLE_COMPILER)
method->SetEntryPointFromPortableCompiledCode(nullptr);
+#endif
method->SetEntryPointFromQuickCompiledCode(nullptr);
DCHECK_NE(instruction_set_, kNone);
return method.Get();