summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick/gen_invoke.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dex/quick/gen_invoke.cc')
-rw-r--r--compiler/dex/quick/gen_invoke.cc204
1 files changed, 11 insertions, 193 deletions
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index d1a9a132bc..469c577071 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -15,6 +15,9 @@
*/
#include "dex/compiler_ir.h"
+#include "dex/frontend.h"
+#include "dex/quick/dex_file_method_inliner.h"
+#include "dex/quick/dex_file_to_method_inliner_map.h"
#include "dex_file-inl.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "invoke_type.h"
@@ -1227,202 +1230,17 @@ bool Mir2Lir::GenInlinedUnsafePut(CallInfo* info, bool is_long,
return true;
}
-bool Mir2Lir::GenIntrinsic(CallInfo* info) {
- if (info->opt_flags & MIR_INLINED) {
- return false;
- }
- /*
- * TODO: move these to a target-specific structured constant array
- * and use a generic match function. The list of intrinsics may be
- * slightly different depending on target.
- * TODO: Fold this into a matching function that runs during
- * basic block building. This should be part of the action for
- * small method inlining and recognition of the special object init
- * method. By doing this during basic block construction, we can also
- * take advantage of/generate new useful dataflow info.
- */
- const DexFile::MethodId& target_mid = cu_->dex_file->GetMethodId(info->index);
- const DexFile::TypeId& declaring_type = cu_->dex_file->GetTypeId(target_mid.class_idx_);
- StringPiece tgt_methods_declaring_class(
- cu_->dex_file->StringDataByIdx(declaring_type.descriptor_idx_));
- if (tgt_methods_declaring_class.starts_with("Ljava/lang/")) {
- tgt_methods_declaring_class.remove_prefix(sizeof("Ljava/lang/") - 1);
- if (tgt_methods_declaring_class.starts_with("Double;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "long java.lang.Double.doubleToRawLongBits(double)") {
- return GenInlinedDoubleCvt(info);
- }
- if (tgt_method == "double java.lang.Double.longBitsToDouble(long)") {
- return GenInlinedDoubleCvt(info);
- }
- } else if (tgt_methods_declaring_class.starts_with("Float;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "int java.lang.Float.floatToRawIntBits(float)") {
- return GenInlinedFloatCvt(info);
- }
- if (tgt_method == "float java.lang.Float.intBitsToFloat(int)") {
- return GenInlinedFloatCvt(info);
- }
- } else if (tgt_methods_declaring_class.starts_with("Integer;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "int java.lang.Integer.reverseBytes(int)") {
- return GenInlinedReverseBytes(info, kWord);
- }
- } else if (tgt_methods_declaring_class.starts_with("Long;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "long java.lang.Long.reverseBytes(long)") {
- return GenInlinedReverseBytes(info, kLong);
- }
- } else if (tgt_methods_declaring_class.starts_with("Math;") ||
- tgt_methods_declaring_class.starts_with("StrictMath;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "int java.lang.Math.abs(int)" ||
- tgt_method == "int java.lang.StrictMath.abs(int)") {
- return GenInlinedAbsInt(info);
- }
- if (tgt_method == "long java.lang.Math.abs(long)" ||
- tgt_method == "long java.lang.StrictMath.abs(long)") {
- return GenInlinedAbsLong(info);
- }
- if (tgt_method == "int java.lang.Math.max(int, int)" ||
- tgt_method == "int java.lang.StrictMath.max(int, int)") {
- return GenInlinedMinMaxInt(info, false /* is_min */);
- }
- if (tgt_method == "int java.lang.Math.min(int, int)" ||
- tgt_method == "int java.lang.StrictMath.min(int, int)") {
- return GenInlinedMinMaxInt(info, true /* is_min */);
- }
- if (tgt_method == "double java.lang.Math.sqrt(double)" ||
- tgt_method == "double java.lang.StrictMath.sqrt(double)") {
- return GenInlinedSqrt(info);
- }
- } else if (tgt_methods_declaring_class.starts_with("Short;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "short java.lang.Short.reverseBytes(short)") {
- return GenInlinedReverseBytes(info, kSignedHalf);
- }
- } else if (tgt_methods_declaring_class.starts_with("String;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "char java.lang.String.charAt(int)") {
- return GenInlinedCharAt(info);
- }
- if (tgt_method == "int java.lang.String.compareTo(java.lang.String)") {
- return GenInlinedStringCompareTo(info);
- }
- if (tgt_method == "boolean java.lang.String.is_empty()") {
- return GenInlinedStringIsEmptyOrLength(info, true /* is_empty */);
- }
- if (tgt_method == "int java.lang.String.index_of(int, int)") {
- return GenInlinedIndexOf(info, false /* base 0 */);
- }
- if (tgt_method == "int java.lang.String.index_of(int)") {
- return GenInlinedIndexOf(info, true /* base 0 */);
- }
- if (tgt_method == "int java.lang.String.length()") {
- return GenInlinedStringIsEmptyOrLength(info, false /* is_empty */);
- }
- } else if (tgt_methods_declaring_class.starts_with("Thread;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "java.lang.Thread java.lang.Thread.currentThread()") {
- return GenInlinedCurrentThread(info);
- }
- }
- } else if (tgt_methods_declaring_class.starts_with("Llibcore/io/Memory;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "byte libcore.io.Memory.peekByte(long)") {
- return GenInlinedPeek(info, kSignedByte);
- }
- if (tgt_method == "int libcore.io.Memory.peekIntNative(long)") {
- return GenInlinedPeek(info, kWord);
- }
- if (tgt_method == "long libcore.io.Memory.peekLongNative(long)") {
- return GenInlinedPeek(info, kLong);
- }
- if (tgt_method == "short libcore.io.Memory.peekShortNative(long)") {
- return GenInlinedPeek(info, kSignedHalf);
- }
- if (tgt_method == "void libcore.io.Memory.pokeByte(long, byte)") {
- return GenInlinedPoke(info, kSignedByte);
- }
- if (tgt_method == "void libcore.io.Memory.pokeIntNative(long, int)") {
- return GenInlinedPoke(info, kWord);
- }
- if (tgt_method == "void libcore.io.Memory.pokeLongNative(long, long)") {
- return GenInlinedPoke(info, kLong);
- }
- if (tgt_method == "void libcore.io.Memory.pokeShortNative(long, short)") {
- return GenInlinedPoke(info, kSignedHalf);
- }
- } else if (tgt_methods_declaring_class.starts_with("Lsun/misc/Unsafe;")) {
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") {
- return GenInlinedCas32(info, false);
- }
- if (tgt_method == "boolean sun.misc.Unsafe.compareAndSwapObject(java.lang.Object, long, java.lang.Object, java.lang.Object)") {
- return GenInlinedCas32(info, true);
- }
- if (tgt_method == "int sun.misc.Unsafe.getInt(java.lang.Object, long)") {
- return GenInlinedUnsafeGet(info, false /* is_long */, false /* is_volatile */);
- }
- if (tgt_method == "int sun.misc.Unsafe.getIntVolatile(java.lang.Object, long)") {
- return GenInlinedUnsafeGet(info, false /* is_long */, true /* is_volatile */);
- }
- if (tgt_method == "void sun.misc.Unsafe.putInt(java.lang.Object, long, int)") {
- return GenInlinedUnsafePut(info, false /* is_long */, false /* is_object */,
- false /* is_volatile */, false /* is_ordered */);
- }
- if (tgt_method == "void sun.misc.Unsafe.putIntVolatile(java.lang.Object, long, int)") {
- return GenInlinedUnsafePut(info, false /* is_long */, false /* is_object */,
- true /* is_volatile */, false /* is_ordered */);
- }
- if (tgt_method == "void sun.misc.Unsafe.putOrderedInt(java.lang.Object, long, int)") {
- return GenInlinedUnsafePut(info, false /* is_long */, false /* is_object */,
- false /* is_volatile */, true /* is_ordered */);
- }
- if (tgt_method == "long sun.misc.Unsafe.getLong(java.lang.Object, long)") {
- return GenInlinedUnsafeGet(info, true /* is_long */, false /* is_volatile */);
- }
- if (tgt_method == "long sun.misc.Unsafe.getLongVolatile(java.lang.Object, long)") {
- return GenInlinedUnsafeGet(info, true /* is_long */, true /* is_volatile */);
- }
- if (tgt_method == "void sun.misc.Unsafe.putLong(java.lang.Object, long, long)") {
- return GenInlinedUnsafePut(info, true /* is_long */, false /* is_object */,
- false /* is_volatile */, false /* is_ordered */);
- }
- if (tgt_method == "void sun.misc.Unsafe.putLongVolatile(java.lang.Object, long, long)") {
- return GenInlinedUnsafePut(info, true /* is_long */, false /* is_object */,
- true /* is_volatile */, false /* is_ordered */);
- }
- if (tgt_method == "void sun.misc.Unsafe.putOrderedLong(java.lang.Object, long, long)") {
- return GenInlinedUnsafePut(info, true /* is_long */, false /* is_object */,
- false /* is_volatile */, true /* is_ordered */);
- }
- if (tgt_method == "java.lang.Object sun.misc.Unsafe.getObject(java.lang.Object, long)") {
- return GenInlinedUnsafeGet(info, false /* is_long */, false /* is_volatile */);
- }
- if (tgt_method == "java.lang.Object sun.misc.Unsafe.getObjectVolatile(java.lang.Object, long)") {
- return GenInlinedUnsafeGet(info, false /* is_long */, true /* is_volatile */);
- }
- if (tgt_method == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") {
- return GenInlinedUnsafePut(info, false /* is_long */, true /* is_object */,
- false /* is_volatile */, false /* is_ordered */);
- }
- if (tgt_method == "void sun.misc.Unsafe.putObjectVolatile(java.lang.Object, long, java.lang.Object)") {
- return GenInlinedUnsafePut(info, false /* is_long */, true /* is_object */,
- true /* is_volatile */, false /* is_ordered */);
+void Mir2Lir::GenInvoke(CallInfo* info) {
+ if (!(info->opt_flags & MIR_INLINED)) {
+ if (inliner_ == nullptr) {
+ QuickCompilerContext* context = reinterpret_cast<QuickCompilerContext*>(
+ cu_->compiler_driver->GetCompilerContext());
+ inliner_ = &context->GetInlinerMap()->GetMethodInliner(cu_->dex_file);
}
- if (tgt_method == "void sun.misc.Unsafe.putOrderedObject(java.lang.Object, long, java.lang.Object)") {
- return GenInlinedUnsafePut(info, false /* is_long */, true /* is_object */,
- false /* is_volatile */, true /* is_ordered */);
+ if (inliner_->GenIntrinsic(this, info)) {
+ return;
}
}
- return false;
-}
-
-void Mir2Lir::GenInvoke(CallInfo* info) {
- if (GenIntrinsic(info)) {
- return;
- }
InvokeType original_type = info->type; // avoiding mutation by ComputeInvokeInfo
int call_state = 0;
LIR* null_ck;