Revert "Revert "Revert "Revert "Add intrinsic for Reference.get()""""
Fixed TargetReg issue causing build failure for x86.
This reverts commit 9e82bd3f0ce9e5f5777bea2f752ff3e251d32f9f.
Change-Id: I7e6a526954467aaf68deeed999880dfe9aa5f06e
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index 45dd7f0..0e46c96 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -48,6 +48,7 @@
true, // kIntrinsicMinMaxFloat
true, // kIntrinsicMinMaxDouble
true, // kIntrinsicSqrt
+ false, // kIntrinsicGet
false, // kIntrinsicCharAt
false, // kIntrinsicCompareTo
false, // kIntrinsicIsEmptyOrLength
@@ -74,6 +75,7 @@
COMPILE_ASSERT(kIntrinsicIsStatic[kIntrinsicMinMaxFloat], MinMaxFloat_must_be_static);
COMPILE_ASSERT(kIntrinsicIsStatic[kIntrinsicMinMaxDouble], MinMaxDouble_must_be_static);
COMPILE_ASSERT(kIntrinsicIsStatic[kIntrinsicSqrt], Sqrt_must_be_static);
+COMPILE_ASSERT(!kIntrinsicIsStatic[kIntrinsicGet], Get_must_not_be_static);
COMPILE_ASSERT(!kIntrinsicIsStatic[kIntrinsicCharAt], CharAt_must_not_be_static);
COMPILE_ASSERT(!kIntrinsicIsStatic[kIntrinsicCompareTo], CompareTo_must_not_be_static);
COMPILE_ASSERT(!kIntrinsicIsStatic[kIntrinsicIsEmptyOrLength], IsEmptyOrLength_must_not_be_static);
@@ -126,6 +128,7 @@
"D", // kClassCacheDouble
"V", // kClassCacheVoid
"Ljava/lang/Object;", // kClassCacheJavaLangObject
+ "Ljava/lang/ref/Reference;", // kClassCacheJavaLangRefReference
"Ljava/lang/String;", // kClassCacheJavaLangString
"Ljava/lang/Double;", // kClassCacheJavaLangDouble
"Ljava/lang/Float;", // kClassCacheJavaLangFloat
@@ -152,6 +155,7 @@
"max", // kNameCacheMax
"min", // kNameCacheMin
"sqrt", // kNameCacheSqrt
+ "get", // kNameCacheGet
"charAt", // kNameCacheCharAt
"compareTo", // kNameCacheCompareTo
"isEmpty", // kNameCacheIsEmpty
@@ -220,6 +224,8 @@
{ kClassCacheBoolean, 0, { } },
// kProtoCache_I
{ kClassCacheInt, 0, { } },
+ // kProtoCache_Object
+ { kClassCacheJavaLangObject, 0, { } },
// kProtoCache_Thread
{ kClassCacheJavaLangThread, 0, { } },
// kProtoCacheJ_B
@@ -308,6 +314,8 @@
INTRINSIC(JavaLangMath, Sqrt, D_D, kIntrinsicSqrt, 0),
INTRINSIC(JavaLangStrictMath, Sqrt, D_D, kIntrinsicSqrt, 0),
+ INTRINSIC(JavaLangRefReference, Get, _Object, kIntrinsicGet, 0),
+
INTRINSIC(JavaLangString, CharAt, I_C, kIntrinsicCharAt, 0),
INTRINSIC(JavaLangString, CompareTo, String_I, kIntrinsicCompareTo, 0),
INTRINSIC(JavaLangString, IsEmpty, _Z, kIntrinsicIsEmptyOrLength, kIntrinsicFlagIsEmpty),
@@ -428,6 +436,8 @@
return backend->GenInlinedMinMaxFP(info, intrinsic.d.data & kIntrinsicFlagMin, true /* is_double */);
case kIntrinsicSqrt:
return backend->GenInlinedSqrt(info);
+ case kIntrinsicGet:
+ return backend->GenInlinedGet(info);
case kIntrinsicCharAt:
return backend->GenInlinedCharAt(info);
case kIntrinsicCompareTo:
diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h
index 5b3b104..cb8c165 100644
--- a/compiler/dex/quick/dex_file_method_inliner.h
+++ b/compiler/dex/quick/dex_file_method_inliner.h
@@ -107,6 +107,7 @@
kClassCacheDouble,
kClassCacheVoid,
kClassCacheJavaLangObject,
+ kClassCacheJavaLangRefReference,
kClassCacheJavaLangString,
kClassCacheJavaLangDouble,
kClassCacheJavaLangFloat,
@@ -140,6 +141,7 @@
kNameCacheMax,
kNameCacheMin,
kNameCacheSqrt,
+ kNameCacheGet,
kNameCacheCharAt,
kNameCacheCompareTo,
kNameCacheIsEmpty,
@@ -199,6 +201,7 @@
kProtoCacheString_I,
kProtoCache_Z,
kProtoCache_I,
+ kProtoCache_Object,
kProtoCache_Thread,
kProtoCacheJ_B,
kProtoCacheJ_I,
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 79065b3..9dedeae 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -23,9 +23,12 @@
#include "invoke_type.h"
#include "mirror/array.h"
#include "mirror/class-inl.h"
+#include "mirror/dex_cache.h"
#include "mirror/object_array-inl.h"
+#include "mirror/reference-inl.h"
#include "mirror/string.h"
#include "mir_to_lir-inl.h"
+#include "scoped_thread_state_change.h"
#include "x86/codegen_x86.h"
namespace art {
@@ -1218,6 +1221,88 @@
return res;
}
+bool Mir2Lir::GenInlinedGet(CallInfo* info) {
+ if (cu_->instruction_set == kMips) {
+ // TODO - add Mips implementation
+ return false;
+ }
+
+ // the refrence class is stored in the image dex file which might not be the same as the cu's
+ // dex file. Query the reference class for the image dex file then reset to starting dex file
+ // in after loading class type.
+ uint16_t type_idx = 0;
+ const DexFile* ref_dex_file = nullptr;
+ {
+ ScopedObjectAccess soa(Thread::Current());
+ type_idx = mirror::Reference::GetJavaLangRefReference()->GetDexTypeIndex();
+ ref_dex_file = mirror::Reference::GetJavaLangRefReference()->GetDexCache()->GetDexFile();
+ }
+ CHECK(LIKELY(ref_dex_file != nullptr));
+
+ // address is either static within the image file, or needs to be patched up after compilation.
+ bool unused_type_initialized;
+ bool use_direct_type_ptr;
+ uintptr_t direct_type_ptr;
+ bool is_finalizable;
+ const DexFile* old_dex = cu_->dex_file;
+ cu_->dex_file = ref_dex_file;
+ RegStorage reg_class = TargetPtrReg(kArg1);
+ if (!cu_->compiler_driver->CanEmbedTypeInCode(*ref_dex_file, type_idx, &unused_type_initialized,
+ &use_direct_type_ptr, &direct_type_ptr,
+ &is_finalizable) || is_finalizable) {
+ cu_->dex_file = old_dex;
+ // address is not known and post-compile patch is not possible, cannot insert intrinsic.
+ return false;
+ }
+ if (use_direct_type_ptr) {
+ LoadConstant(reg_class, direct_type_ptr);
+ } else {
+ LoadClassType(type_idx, kArg1);
+ }
+ cu_->dex_file = old_dex;
+
+ // get the offset for flags in reference class.
+ uint32_t slow_path_flag_offset = 0;
+ uint32_t disable_flag_offset = 0;
+ {
+ ScopedObjectAccess soa(Thread::Current());
+ mirror::Class* reference_class = mirror::Reference::GetJavaLangRefReference();
+ slow_path_flag_offset = reference_class->GetSlowPathFlagOffset().Uint32Value();
+ disable_flag_offset = reference_class->GetDisableIntrinsicFlagOffset().Uint32Value();
+ }
+ CHECK(slow_path_flag_offset && disable_flag_offset &&
+ (slow_path_flag_offset != disable_flag_offset));
+
+ // intrinsic logic start.
+ RegLocation rl_obj = info->args[0];
+ rl_obj = LoadValue(rl_obj);
+
+ RegStorage reg_slow_path = AllocTemp();
+ RegStorage reg_disabled = AllocTemp();
+ Load32Disp(reg_class, slow_path_flag_offset, reg_slow_path);
+ Load32Disp(reg_class, disable_flag_offset, reg_disabled);
+ OpRegRegReg(kOpOr, reg_slow_path, reg_slow_path, reg_disabled);
+ FreeTemp(reg_disabled);
+
+ // if slow path, jump to JNI path target
+ LIR* slow_path_branch = OpCmpImmBranch(kCondNe, reg_slow_path, 0, nullptr);
+ FreeTemp(reg_slow_path);
+
+ // slow path not enabled, simply load the referent of the reference object
+ RegLocation rl_dest = InlineTarget(info);
+ RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true);
+ GenNullCheck(rl_obj.reg, info->opt_flags);
+ LoadRefDisp(rl_obj.reg, mirror::Reference::ReferentOffset().Int32Value(), rl_result.reg,
+ kNotVolatile);
+ MarkPossibleNullPointerException(info->opt_flags);
+ StoreValue(rl_dest, rl_result);
+
+ LIR* intrinsic_finish = NewLIR0(kPseudoTargetLabel);
+ AddIntrinsicSlowPath(info, slow_path_branch, intrinsic_finish);
+
+ return true;
+}
+
bool Mir2Lir::GenInlinedCharAt(CallInfo* info) {
if (cu_->instruction_set == kMips) {
// TODO - add Mips implementation
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index fd0fe6e..c68ad6b 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -982,6 +982,7 @@
*/
RegLocation InlineTargetWide(CallInfo* info);
+ bool GenInlinedGet(CallInfo* info);
bool GenInlinedCharAt(CallInfo* info);
bool GenInlinedStringIsEmptyOrLength(CallInfo* info, bool is_empty);
virtual bool GenInlinedReverseBits(CallInfo* info, OpSize size);