17de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik/* 27de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * Copyright (C) 2016 The Android Open Source Project 37de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * 47de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * Licensed under the Apache License, Version 2.0 (the "License"); 57de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * you may not use this file except in compliance with the License. 67de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * You may obtain a copy of the License at 77de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * 87de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * http://www.apache.org/licenses/LICENSE-2.0 97de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * 107de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * Unless required by applicable law or agreed to in writing, software 117de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * distributed under the License is distributed on an "AS IS" BASIS, 127de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * See the License for the specific language governing permissions and 147de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * limitations under the License. 157de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik */ 167de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 177de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik#include "base/arena_allocator.h" 187de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik#include "builder.h" 197de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik#include "nodes.h" 207de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik#include "object_lock.h" 217de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik#include "optimizing_unit_test.h" 227de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik#include "reference_type_propagation.h" 237de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 247de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Biknamespace art { 257de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 267de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik/** 277de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * Fixture class for unit testing the ReferenceTypePropagation phase. Used to verify the 287de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik * functionality of methods and situations that are hard to set up with checker tests. 297de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik */ 307de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bikclass ReferenceTypePropagationTest : public CommonCompilerTest { 317de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik public: 327de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypePropagationTest() : pool_(), allocator_(&pool_) { 337de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik graph_ = CreateGraph(&allocator_); 347de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik } 357de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 367de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ~ReferenceTypePropagationTest() { } 377de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 387de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik void SetupPropagation(StackHandleScopeCollection* handles) { 397de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik graph_->InitializeInexactObjectRTI(handles); 40a4336d253b88f95c49891a8084579a4599785e90Vladimir Marko propagation_ = new (&allocator_) ReferenceTypePropagation(graph_, 41a4336d253b88f95c49891a8084579a4599785e90Vladimir Marko Handle<mirror::DexCache>(), 42a4336d253b88f95c49891a8084579a4599785e90Vladimir Marko handles, 43a4336d253b88f95c49891a8084579a4599785e90Vladimir Marko true, 44a4336d253b88f95c49891a8084579a4599785e90Vladimir Marko "test_prop"); 457de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik } 467de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 477de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Relay method to merge type in reference type propagation. 487de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a, 497de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik const ReferenceTypeInfo& b) SHARED_REQUIRES(Locks::mutator_lock_) { 507de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik return propagation_->MergeTypes(a, b); 517de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik } 527de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 537de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Helper method to construct an invalid type. 547de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo InvalidType() { 557de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik return ReferenceTypeInfo::CreateInvalid(); 567de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik } 577de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 587de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Helper method to construct the Object type. 597de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo ObjectType(bool is_exact = true) SHARED_REQUIRES(Locks::mutator_lock_) { 607de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik return ReferenceTypeInfo::Create(propagation_->handle_cache_.GetObjectClassHandle(), is_exact); 617de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik } 627de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 637de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Helper method to construct the String type. 647de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo StringType(bool is_exact = true) SHARED_REQUIRES(Locks::mutator_lock_) { 657de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik return ReferenceTypeInfo::Create(propagation_->handle_cache_.GetStringClassHandle(), is_exact); 667de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik } 677de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 687de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // General building fields. 697de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ArenaPool pool_; 707de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ArenaAllocator allocator_; 717de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik HGraph* graph_; 727de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 737de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypePropagation* propagation_; 747de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik}; 757de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 767de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik// 777de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik// The actual ReferenceTypePropgation unit tests. 787de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik// 797de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 807de2439d357710aaf8bfe02b8cf9c196d3c77705Aart BikTEST_F(ReferenceTypePropagationTest, ProperSetup) { 817de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ScopedObjectAccess soa(Thread::Current()); 827de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik StackHandleScopeCollection handles(soa.Self()); 837de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik SetupPropagation(&handles); 847de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 857de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(propagation_ != nullptr); 867de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(graph_->GetInexactObjectRti().IsEqual(ObjectType(false))); 877de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik} 887de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 897de2439d357710aaf8bfe02b8cf9c196d3c77705Aart BikTEST_F(ReferenceTypePropagationTest, MergeInvalidTypes) { 907de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ScopedObjectAccess soa(Thread::Current()); 917de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik StackHandleScopeCollection handles(soa.Self()); 927de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik SetupPropagation(&handles); 937de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 947de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Two invalid types. 957de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t1(MergeTypes(InvalidType(), InvalidType())); 967de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_FALSE(t1.IsValid()); 977de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_FALSE(t1.IsExact()); 987de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t1.IsEqual(InvalidType())); 997de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 1007de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Valid type on right. 1017de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t2(MergeTypes(InvalidType(), ObjectType())); 1027de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t2.IsValid()); 1037de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t2.IsExact()); 1047de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t2.IsEqual(ObjectType())); 1057de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t3(MergeTypes(InvalidType(), StringType())); 1067de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t3.IsValid()); 1077de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t3.IsExact()); 1087de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t3.IsEqual(StringType())); 1097de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 1107de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Valid type on left. 1117de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t4(MergeTypes(ObjectType(), InvalidType())); 1127de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t4.IsValid()); 1137de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t4.IsExact()); 1147de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t4.IsEqual(ObjectType())); 1157de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t5(MergeTypes(StringType(), InvalidType())); 1167de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t5.IsValid()); 1177de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t5.IsExact()); 1187de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t5.IsEqual(StringType())); 1197de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik} 1207de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 1217de2439d357710aaf8bfe02b8cf9c196d3c77705Aart BikTEST_F(ReferenceTypePropagationTest, MergeValidTypes) { 1227de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ScopedObjectAccess soa(Thread::Current()); 1237de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik StackHandleScopeCollection handles(soa.Self()); 1247de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik SetupPropagation(&handles); 1257de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 1267de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Same types. 1277de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t1(MergeTypes(ObjectType(), ObjectType())); 1287de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t1.IsValid()); 1297de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t1.IsExact()); 1307de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t1.IsEqual(ObjectType())); 1317de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t2(MergeTypes(StringType(), StringType())); 1327de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t2.IsValid()); 1337de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t2.IsExact()); 1347de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t2.IsEqual(StringType())); 1357de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 1367de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Left is super class of right. 1377de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t3(MergeTypes(ObjectType(), StringType())); 1387de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t3.IsValid()); 1397de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_FALSE(t3.IsExact()); 1407de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t3.IsEqual(ObjectType(false))); 1417de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 1427de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Right is super class of left. 1437de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t4(MergeTypes(StringType(), ObjectType())); 1447de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t4.IsValid()); 1457de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_FALSE(t4.IsExact()); 1467de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t4.IsEqual(ObjectType(false))); 1477de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 1487de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik // Same types, but one or both are inexact. 1497de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t5(MergeTypes(ObjectType(false), ObjectType())); 1507de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t5.IsValid()); 1517de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_FALSE(t5.IsExact()); 1527de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t5.IsEqual(ObjectType(false))); 1537de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t6(MergeTypes(ObjectType(), ObjectType(false))); 1547de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t6.IsValid()); 1557de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_FALSE(t6.IsExact()); 1567de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t6.IsEqual(ObjectType(false))); 1577de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik ReferenceTypeInfo t7(MergeTypes(ObjectType(false), ObjectType(false))); 1587de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t7.IsValid()); 1597de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_FALSE(t7.IsExact()); 1607de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik EXPECT_TRUE(t7.IsEqual(ObjectType(false))); 1617de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik} 1627de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 1637de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik} // namespace art 1647de2439d357710aaf8bfe02b8cf9c196d3c77705Aart Bik 165