Home | History | Annotate | Download | only in optimizing
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "base/arena_allocator.h"
     18 #include "builder.h"
     19 #include "nodes.h"
     20 #include "object_lock.h"
     21 #include "optimizing_unit_test.h"
     22 #include "reference_type_propagation.h"
     23 
     24 namespace art {
     25 
     26 /**
     27  * Fixture class for unit testing the ReferenceTypePropagation phase. Used to verify the
     28  * functionality of methods and situations that are hard to set up with checker tests.
     29  */
     30 class ReferenceTypePropagationTest : public CommonCompilerTest {
     31  public:
     32   ReferenceTypePropagationTest() : pool_(), allocator_(&pool_) {
     33     graph_ = CreateGraph(&allocator_);
     34   }
     35 
     36   ~ReferenceTypePropagationTest() { }
     37 
     38   void SetupPropagation(StackHandleScopeCollection* handles) {
     39     graph_->InitializeInexactObjectRTI(handles);
     40     propagation_ = new (&allocator_) ReferenceTypePropagation(graph_,
     41                                                               Handle<mirror::DexCache>(),
     42                                                               handles,
     43                                                               true,
     44                                                               "test_prop");
     45   }
     46 
     47   // Relay method to merge type in reference type propagation.
     48   ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a,
     49                                const ReferenceTypeInfo& b) SHARED_REQUIRES(Locks::mutator_lock_) {
     50     return propagation_->MergeTypes(a, b);
     51   }
     52 
     53   // Helper method to construct an invalid type.
     54   ReferenceTypeInfo InvalidType() {
     55     return ReferenceTypeInfo::CreateInvalid();
     56   }
     57 
     58   // Helper method to construct the Object type.
     59   ReferenceTypeInfo ObjectType(bool is_exact = true) SHARED_REQUIRES(Locks::mutator_lock_) {
     60     return ReferenceTypeInfo::Create(propagation_->handle_cache_.GetObjectClassHandle(), is_exact);
     61   }
     62 
     63   // Helper method to construct the String type.
     64   ReferenceTypeInfo StringType(bool is_exact = true) SHARED_REQUIRES(Locks::mutator_lock_) {
     65     return ReferenceTypeInfo::Create(propagation_->handle_cache_.GetStringClassHandle(), is_exact);
     66   }
     67 
     68   // General building fields.
     69   ArenaPool pool_;
     70   ArenaAllocator allocator_;
     71   HGraph* graph_;
     72 
     73   ReferenceTypePropagation* propagation_;
     74 };
     75 
     76 //
     77 // The actual ReferenceTypePropgation unit tests.
     78 //
     79 
     80 TEST_F(ReferenceTypePropagationTest, ProperSetup) {
     81   ScopedObjectAccess soa(Thread::Current());
     82   StackHandleScopeCollection handles(soa.Self());
     83   SetupPropagation(&handles);
     84 
     85   EXPECT_TRUE(propagation_ != nullptr);
     86   EXPECT_TRUE(graph_->GetInexactObjectRti().IsEqual(ObjectType(false)));
     87 }
     88 
     89 TEST_F(ReferenceTypePropagationTest, MergeInvalidTypes) {
     90   ScopedObjectAccess soa(Thread::Current());
     91   StackHandleScopeCollection handles(soa.Self());
     92   SetupPropagation(&handles);
     93 
     94   // Two invalid types.
     95   ReferenceTypeInfo t1(MergeTypes(InvalidType(), InvalidType()));
     96   EXPECT_FALSE(t1.IsValid());
     97   EXPECT_FALSE(t1.IsExact());
     98   EXPECT_TRUE(t1.IsEqual(InvalidType()));
     99 
    100   // Valid type on right.
    101   ReferenceTypeInfo t2(MergeTypes(InvalidType(), ObjectType()));
    102   EXPECT_TRUE(t2.IsValid());
    103   EXPECT_TRUE(t2.IsExact());
    104   EXPECT_TRUE(t2.IsEqual(ObjectType()));
    105   ReferenceTypeInfo t3(MergeTypes(InvalidType(), StringType()));
    106   EXPECT_TRUE(t3.IsValid());
    107   EXPECT_TRUE(t3.IsExact());
    108   EXPECT_TRUE(t3.IsEqual(StringType()));
    109 
    110   // Valid type on left.
    111   ReferenceTypeInfo t4(MergeTypes(ObjectType(), InvalidType()));
    112   EXPECT_TRUE(t4.IsValid());
    113   EXPECT_TRUE(t4.IsExact());
    114   EXPECT_TRUE(t4.IsEqual(ObjectType()));
    115   ReferenceTypeInfo t5(MergeTypes(StringType(), InvalidType()));
    116   EXPECT_TRUE(t5.IsValid());
    117   EXPECT_TRUE(t5.IsExact());
    118   EXPECT_TRUE(t5.IsEqual(StringType()));
    119 }
    120 
    121 TEST_F(ReferenceTypePropagationTest, MergeValidTypes) {
    122   ScopedObjectAccess soa(Thread::Current());
    123   StackHandleScopeCollection handles(soa.Self());
    124   SetupPropagation(&handles);
    125 
    126   // Same types.
    127   ReferenceTypeInfo t1(MergeTypes(ObjectType(), ObjectType()));
    128   EXPECT_TRUE(t1.IsValid());
    129   EXPECT_TRUE(t1.IsExact());
    130   EXPECT_TRUE(t1.IsEqual(ObjectType()));
    131   ReferenceTypeInfo t2(MergeTypes(StringType(), StringType()));
    132   EXPECT_TRUE(t2.IsValid());
    133   EXPECT_TRUE(t2.IsExact());
    134   EXPECT_TRUE(t2.IsEqual(StringType()));
    135 
    136   // Left is super class of right.
    137   ReferenceTypeInfo t3(MergeTypes(ObjectType(), StringType()));
    138   EXPECT_TRUE(t3.IsValid());
    139   EXPECT_FALSE(t3.IsExact());
    140   EXPECT_TRUE(t3.IsEqual(ObjectType(false)));
    141 
    142   // Right is super class of left.
    143   ReferenceTypeInfo t4(MergeTypes(StringType(), ObjectType()));
    144   EXPECT_TRUE(t4.IsValid());
    145   EXPECT_FALSE(t4.IsExact());
    146   EXPECT_TRUE(t4.IsEqual(ObjectType(false)));
    147 
    148   // Same types, but one or both are inexact.
    149   ReferenceTypeInfo t5(MergeTypes(ObjectType(false), ObjectType()));
    150   EXPECT_TRUE(t5.IsValid());
    151   EXPECT_FALSE(t5.IsExact());
    152   EXPECT_TRUE(t5.IsEqual(ObjectType(false)));
    153   ReferenceTypeInfo t6(MergeTypes(ObjectType(), ObjectType(false)));
    154   EXPECT_TRUE(t6.IsValid());
    155   EXPECT_FALSE(t6.IsExact());
    156   EXPECT_TRUE(t6.IsEqual(ObjectType(false)));
    157   ReferenceTypeInfo t7(MergeTypes(ObjectType(false), ObjectType(false)));
    158   EXPECT_TRUE(t7.IsValid());
    159   EXPECT_FALSE(t7.IsExact());
    160   EXPECT_TRUE(t7.IsEqual(ObjectType(false)));
    161 }
    162 
    163 }  // namespace art
    164 
    165