OSDN Git Service

Add support to indicate whether intrinsics require a dex cache
authorAgi Csaki <agicsaki@google.com>
Wed, 19 Aug 2015 21:58:14 +0000 (14:58 -0700)
committerAgi Csaki <agicsaki@google.com>
Thu, 20 Aug 2015 01:51:32 +0000 (18:51 -0700)
A structural change to indicate whether a given intrinsic requires access
to a dex cache.  I updated the needs_environment_ field to indicate
whether an HInvoke needs an environment or a dex cache, and if an HInvoke
represents an intrisified method, we utilize this field to determine if
the HInvoke needs a dex cache.

Bug: 21481923
Change-Id: I9dd25a385e1a1397603da6c4c43f6c1aea511b32

compiler/optimizing/intrinsics.cc
compiler/optimizing/intrinsics_arm.h
compiler/optimizing/intrinsics_arm64.h
compiler/optimizing/intrinsics_list.h
compiler/optimizing/intrinsics_x86.h
compiler/optimizing/intrinsics_x86_64.h
compiler/optimizing/nodes.h

index 3db9816..075ec1e 100644 (file)
@@ -31,7 +31,7 @@ static inline InvokeType GetIntrinsicInvokeType(Intrinsics i) {
   switch (i) {
     case Intrinsics::kNone:
       return kInterface;  // Non-sensical for intrinsic.
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache) \
     case Intrinsics::k ## Name:               \
       return IsStatic;
 #include "intrinsics_list.h"
@@ -43,19 +43,19 @@ INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
 }
 
 // Function that returns whether an intrinsic needs an environment or not.
-static inline IntrinsicNeedsEnvironment IntrinsicNeedsEnvironment(Intrinsics i) {
+static inline IntrinsicNeedsEnvironmentOrCache NeedsEnvironmentOrCache(Intrinsics i) {
   switch (i) {
     case Intrinsics::kNone:
-      return kNeedsEnvironment;  // Non-sensical for intrinsic.
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \
+      return kNeedsEnvironmentOrCache;  // Non-sensical for intrinsic.
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache) \
     case Intrinsics::k ## Name:               \
-      return NeedsEnvironment;
+      return NeedsEnvironmentOrCache;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
 #undef INTRINSICS_LIST
 #undef OPTIMIZING_INTRINSICS
   }
-  return kNeedsEnvironment;
+  return kNeedsEnvironmentOrCache;
 }
 
 static Primitive::Type GetType(uint64_t data, bool is_op_size) {
@@ -376,7 +376,7 @@ void IntrinsicsRecognizer::Run() {
                            << intrinsic << " for "
                            << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile());
             } else {
-              invoke->SetIntrinsic(intrinsic, IntrinsicNeedsEnvironment(intrinsic));
+              invoke->SetIntrinsic(intrinsic, NeedsEnvironmentOrCache(intrinsic));
             }
           }
         }
@@ -390,7 +390,7 @@ std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) {
     case Intrinsics::kNone:
       os << "None";
       break;
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache) \
     case Intrinsics::k ## Name: \
       os << # Name; \
       break;
index f013bd6..2abb605 100644 (file)
@@ -38,7 +38,7 @@ class IntrinsicLocationsBuilderARM FINAL : public IntrinsicVisitor {
 
   // Define visitor methods.
 
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment)   \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache)   \
   void Visit ## Name(HInvoke* invoke) OVERRIDE;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
@@ -64,7 +64,7 @@ class IntrinsicCodeGeneratorARM FINAL : public IntrinsicVisitor {
 
   // Define visitor methods.
 
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment)   \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache)   \
   void Visit ## Name(HInvoke* invoke) OVERRIDE;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
index ebaf5e5..4250ecf 100644 (file)
@@ -41,7 +41,7 @@ class IntrinsicLocationsBuilderARM64 FINAL : public IntrinsicVisitor {
 
   // Define visitor methods.
 
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment)   \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache)   \
   void Visit ## Name(HInvoke* invoke) OVERRIDE;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
@@ -65,7 +65,7 @@ class IntrinsicCodeGeneratorARM64 FINAL : public IntrinsicVisitor {
 
   // Define visitor methods.
 
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment)   \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache)   \
   void Visit ## Name(HInvoke* invoke) OVERRIDE;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
index 15ee5d4..7e5339e 100644 (file)
 // environment.
 
 #define INTRINSICS_LIST(V) \
-  V(DoubleDoubleToRawLongBits, kStatic, kNeedsEnvironment) \
-  V(DoubleLongBitsToDouble, kStatic, kNeedsEnvironment) \
-  V(FloatFloatToRawIntBits, kStatic, kNeedsEnvironment) \
-  V(FloatIntBitsToFloat, kStatic, kNeedsEnvironment) \
-  V(IntegerReverse, kStatic, kNeedsEnvironment) \
-  V(IntegerReverseBytes, kStatic, kNeedsEnvironment) \
-  V(IntegerNumberOfLeadingZeros, kStatic, kNeedsEnvironment) \
-  V(LongReverse, kStatic, kNeedsEnvironment) \
-  V(LongReverseBytes, kStatic, kNeedsEnvironment) \
-  V(LongNumberOfLeadingZeros, kStatic, kNeedsEnvironment) \
-  V(ShortReverseBytes, kStatic, kNeedsEnvironment) \
-  V(MathAbsDouble, kStatic, kNeedsEnvironment) \
-  V(MathAbsFloat, kStatic, kNeedsEnvironment) \
-  V(MathAbsLong, kStatic, kNeedsEnvironment) \
-  V(MathAbsInt, kStatic, kNeedsEnvironment) \
-  V(MathMinDoubleDouble, kStatic, kNeedsEnvironment) \
-  V(MathMinFloatFloat, kStatic, kNeedsEnvironment) \
-  V(MathMinLongLong, kStatic, kNeedsEnvironment) \
-  V(MathMinIntInt, kStatic, kNeedsEnvironment) \
-  V(MathMaxDoubleDouble, kStatic, kNeedsEnvironment) \
-  V(MathMaxFloatFloat, kStatic, kNeedsEnvironment) \
-  V(MathMaxLongLong, kStatic, kNeedsEnvironment) \
-  V(MathMaxIntInt, kStatic, kNeedsEnvironment) \
-  V(MathSqrt, kStatic, kNeedsEnvironment) \
-  V(MathCeil, kStatic, kNeedsEnvironment) \
-  V(MathFloor, kStatic, kNeedsEnvironment) \
-  V(MathRint, kStatic, kNeedsEnvironment) \
-  V(MathRoundDouble, kStatic, kNeedsEnvironment) \
-  V(MathRoundFloat, kStatic, kNeedsEnvironment) \
-  V(SystemArrayCopyChar, kStatic, kNeedsEnvironment) \
-  V(ThreadCurrentThread, kStatic, kNeedsEnvironment) \
-  V(MemoryPeekByte, kStatic, kNeedsEnvironment) \
-  V(MemoryPeekIntNative, kStatic, kNeedsEnvironment) \
-  V(MemoryPeekLongNative, kStatic, kNeedsEnvironment) \
-  V(MemoryPeekShortNative, kStatic, kNeedsEnvironment) \
-  V(MemoryPokeByte, kStatic, kNeedsEnvironment) \
-  V(MemoryPokeIntNative, kStatic, kNeedsEnvironment) \
-  V(MemoryPokeLongNative, kStatic, kNeedsEnvironment) \
-  V(MemoryPokeShortNative, kStatic, kNeedsEnvironment) \
-  V(StringCharAt, kDirect, kNeedsEnvironment) \
-  V(StringCompareTo, kDirect, kNeedsEnvironment) \
-  V(StringEquals, kDirect, kNeedsEnvironment) \
-  V(StringGetCharsNoCheck, kDirect, kNeedsEnvironment) \
-  V(StringIndexOf, kDirect, kNeedsEnvironment) \
-  V(StringIndexOfAfter, kDirect, kNeedsEnvironment) \
-  V(StringNewStringFromBytes, kStatic, kNeedsEnvironment) \
-  V(StringNewStringFromChars, kStatic, kNeedsEnvironment) \
-  V(StringNewStringFromString, kStatic, kNeedsEnvironment) \
-  V(UnsafeCASInt, kDirect, kNeedsEnvironment) \
-  V(UnsafeCASLong, kDirect, kNeedsEnvironment) \
-  V(UnsafeCASObject, kDirect, kNeedsEnvironment) \
-  V(UnsafeGet, kDirect, kNeedsEnvironment) \
-  V(UnsafeGetVolatile, kDirect, kNeedsEnvironment) \
-  V(UnsafeGetObject, kDirect, kNeedsEnvironment) \
-  V(UnsafeGetObjectVolatile, kDirect, kNeedsEnvironment) \
-  V(UnsafeGetLong, kDirect, kNeedsEnvironment) \
-  V(UnsafeGetLongVolatile, kDirect, kNeedsEnvironment) \
-  V(UnsafePut, kDirect, kNeedsEnvironment) \
-  V(UnsafePutOrdered, kDirect, kNeedsEnvironment) \
-  V(UnsafePutVolatile, kDirect, kNeedsEnvironment) \
-  V(UnsafePutObject, kDirect, kNeedsEnvironment) \
-  V(UnsafePutObjectOrdered, kDirect, kNeedsEnvironment) \
-  V(UnsafePutObjectVolatile, kDirect, kNeedsEnvironment) \
-  V(UnsafePutLong, kDirect, kNeedsEnvironment) \
-  V(UnsafePutLongOrdered, kDirect, kNeedsEnvironment) \
-  V(UnsafePutLongVolatile, kDirect, kNeedsEnvironment) \
-  V(ReferenceGetReferent, kDirect, kNeedsEnvironment)
+  V(DoubleDoubleToRawLongBits, kStatic, kNeedsEnvironmentOrCache) \
+  V(DoubleLongBitsToDouble, kStatic, kNeedsEnvironmentOrCache) \
+  V(FloatFloatToRawIntBits, kStatic, kNeedsEnvironmentOrCache) \
+  V(FloatIntBitsToFloat, kStatic, kNeedsEnvironmentOrCache) \
+  V(IntegerReverse, kStatic, kNeedsEnvironmentOrCache) \
+  V(IntegerReverseBytes, kStatic, kNeedsEnvironmentOrCache) \
+  V(IntegerNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache) \
+  V(LongReverse, kStatic, kNeedsEnvironmentOrCache) \
+  V(LongReverseBytes, kStatic, kNeedsEnvironmentOrCache) \
+  V(LongNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache) \
+  V(ShortReverseBytes, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathAbsDouble, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathAbsFloat, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathAbsLong, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathAbsInt, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathMinDoubleDouble, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathMinFloatFloat, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathMinLongLong, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathMinIntInt, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathMaxDoubleDouble, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathMaxFloatFloat, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathMaxLongLong, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathMaxIntInt, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathSqrt, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathCeil, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathFloor, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathRint, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathRoundDouble, kStatic, kNeedsEnvironmentOrCache) \
+  V(MathRoundFloat, kStatic, kNeedsEnvironmentOrCache) \
+  V(SystemArrayCopyChar, kStatic, kNeedsEnvironmentOrCache) \
+  V(ThreadCurrentThread, kStatic, kNeedsEnvironmentOrCache) \
+  V(MemoryPeekByte, kStatic, kNeedsEnvironmentOrCache) \
+  V(MemoryPeekIntNative, kStatic, kNeedsEnvironmentOrCache) \
+  V(MemoryPeekLongNative, kStatic, kNeedsEnvironmentOrCache) \
+  V(MemoryPeekShortNative, kStatic, kNeedsEnvironmentOrCache) \
+  V(MemoryPokeByte, kStatic, kNeedsEnvironmentOrCache) \
+  V(MemoryPokeIntNative, kStatic, kNeedsEnvironmentOrCache) \
+  V(MemoryPokeLongNative, kStatic, kNeedsEnvironmentOrCache) \
+  V(MemoryPokeShortNative, kStatic, kNeedsEnvironmentOrCache) \
+  V(StringCharAt, kDirect, kNeedsEnvironmentOrCache) \
+  V(StringCompareTo, kDirect, kNeedsEnvironmentOrCache) \
+  V(StringEquals, kDirect, kNeedsEnvironmentOrCache) \
+  V(StringGetCharsNoCheck, kDirect, kNeedsEnvironmentOrCache) \
+  V(StringIndexOf, kDirect, kNeedsEnvironmentOrCache) \
+  V(StringIndexOfAfter, kDirect, kNeedsEnvironmentOrCache) \
+  V(StringNewStringFromBytes, kStatic, kNeedsEnvironmentOrCache) \
+  V(StringNewStringFromChars, kStatic, kNeedsEnvironmentOrCache) \
+  V(StringNewStringFromString, kStatic, kNeedsEnvironmentOrCache) \
+  V(UnsafeCASInt, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafeCASLong, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafeCASObject, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafeGet, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafeGetVolatile, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafeGetObject, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafeGetObjectVolatile, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafeGetLong, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafeGetLongVolatile, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePut, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePutOrdered, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePutVolatile, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePutObject, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePutObjectOrdered, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePutObjectVolatile, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePutLong, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePutLongOrdered, kDirect, kNeedsEnvironmentOrCache) \
+  V(UnsafePutLongVolatile, kDirect, kNeedsEnvironmentOrCache) \
+  V(ReferenceGetReferent, kDirect, kNeedsEnvironmentOrCache)
 
 #endif  // ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_
 #undef ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_   // #define is only for lint.
index ac68f39..fefe9c6 100644 (file)
@@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderX86 FINAL : public IntrinsicVisitor {
 
   // Define visitor methods.
 
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment)   \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache)   \
   void Visit ## Name(HInvoke* invoke) OVERRIDE;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
@@ -61,7 +61,7 @@ class IntrinsicCodeGeneratorX86 FINAL : public IntrinsicVisitor {
 
   // Define visitor methods.
 
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment)   \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache)   \
   void Visit ## Name(HInvoke* invoke) OVERRIDE;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
index 17293af..6894e1b 100644 (file)
@@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderX86_64 FINAL : public IntrinsicVisitor {
 
   // Define visitor methods.
 
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment)   \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache)   \
   void Visit ## Name(HInvoke* invoke) OVERRIDE;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
@@ -61,7 +61,7 @@ class IntrinsicCodeGeneratorX86_64 FINAL : public IntrinsicVisitor {
 
   // Define visitor methods.
 
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment)   \
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache)   \
   void Visit ## Name(HInvoke* invoke) OVERRIDE;
 #include "intrinsics_list.h"
 INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
index 7e49199..851dd4f 100644 (file)
@@ -2931,7 +2931,7 @@ class HDoubleConstant : public HConstant {
 };
 
 enum class Intrinsics {
-#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) k ## Name,
+#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache) k ## Name,
 #include "intrinsics_list.h"
   kNone,
   INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
@@ -2940,9 +2940,9 @@ enum class Intrinsics {
 };
 std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic);
 
-enum IntrinsicNeedsEnvironment {
-  kNoEnvironment,        // Intrinsic does not require an environment.
-  kNeedsEnvironment      // Intrinsic requires an environment.
+enum IntrinsicNeedsEnvironmentOrCache {
+  kNoEnvironmentOrCache,        // Intrinsic does not require an environment or dex cache.
+  kNeedsEnvironmentOrCache      // Intrinsic requires an environment or requires a dex cache.
 };
 
 class HInvoke : public HInstruction {
@@ -2951,7 +2951,9 @@ class HInvoke : public HInstruction {
 
   // Runtime needs to walk the stack, so Dex -> Dex calls need to
   // know their environment.
-  bool NeedsEnvironment() const OVERRIDE { return needs_environment_ == kNeedsEnvironment; }
+  bool NeedsEnvironment() const OVERRIDE {
+    return needs_environment_or_cache_ == kNeedsEnvironmentOrCache;
+  }
 
   void SetArgumentAt(size_t index, HInstruction* argument) {
     SetRawInputAt(index, argument);
@@ -2976,9 +2978,9 @@ class HInvoke : public HInstruction {
     return intrinsic_;
   }
 
-  void SetIntrinsic(Intrinsics intrinsic, IntrinsicNeedsEnvironment needs_environment) {
+  void SetIntrinsic(Intrinsics intrinsic, IntrinsicNeedsEnvironmentOrCache needs_env_or_cache) {
     intrinsic_ = intrinsic;
-    needs_environment_ = needs_environment;
+    needs_environment_or_cache_ = needs_env_or_cache;
   }
 
   bool IsFromInlinedInvoke() const {
@@ -3006,7 +3008,7 @@ class HInvoke : public HInstruction {
       dex_method_index_(dex_method_index),
       original_invoke_type_(original_invoke_type),
       intrinsic_(Intrinsics::kNone),
-      needs_environment_(kNeedsEnvironment) {
+      needs_environment_or_cache_(kNeedsEnvironmentOrCache) {
     uint32_t number_of_inputs = number_of_arguments + number_of_other_inputs;
     inputs_.SetSize(number_of_inputs);
   }
@@ -3023,7 +3025,7 @@ class HInvoke : public HInstruction {
   const uint32_t dex_method_index_;
   const InvokeType original_invoke_type_;
   Intrinsics intrinsic_;
-  IntrinsicNeedsEnvironment needs_environment_;
+  IntrinsicNeedsEnvironmentOrCache needs_environment_or_cache_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(HInvoke);
@@ -3148,7 +3150,10 @@ class HInvokeStaticOrDirect : public HInvoke {
   MethodLoadKind GetMethodLoadKind() const { return dispatch_info_.method_load_kind; }
   CodePtrLocation GetCodePtrLocation() const { return dispatch_info_.code_ptr_location; }
   bool IsRecursive() const { return GetMethodLoadKind() == MethodLoadKind::kRecursive; }
-  bool NeedsDexCache() const OVERRIDE { return !IsRecursive() && !IsStringInit(); }
+  bool NeedsDexCache() const OVERRIDE {
+    if (intrinsic_ != Intrinsics::kNone) { return needs_environment_or_cache_; }
+    return !IsRecursive() && !IsStringInit();
+  }
   bool IsStringInit() const { return GetMethodLoadKind() == MethodLoadKind::kStringInit; }
   uint32_t GetCurrentMethodInputIndex() const { return GetNumberOfArguments(); }
   bool HasMethodAddress() const { return GetMethodLoadKind() == MethodLoadKind::kDirectAddress; }