/*
* Copyright ( C ) 2015 The Android Open Source Project
*
* Licensed under the Apache License , Version 2 . 0 ( the " License " ) ;
* you may not read this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
#include <gtest/gtest.h>
#include "base/macros.h"
#include "data_type.h"
#include "nodes.h"
namespace art HIDDEN {
// Only runtime types other than void are allowed.
static const DataType::Type kTestTypes[] = {
DataType::Type::kReference,
DataType::Type::kBool,
DataType::Type::kInt8,
DataType::Type::kUint16,
DataType::Type::kInt16,
DataType::Type::kInt32,
DataType::Type::kInt64,
DataType::Type::kFloat32,
DataType::Type::kFloat64,
};
/**
* Tests for the SideEffects class .
*/
//
// Helper methods.
//
void testWriteAndReadEffects(SideEffects write, SideEffects read) {
EXPECT_FALSE(write.DoesNothing());
EXPECT_FALSE(read.DoesNothing());
EXPECT_TRUE(write.DoesAnyWrite());
EXPECT_FALSE(write.DoesAnyRead());
EXPECT_FALSE(read.DoesAnyWrite());
EXPECT_TRUE(read.DoesAnyRead());
// All-dependences.
SideEffects all = SideEffects::All();
EXPECT_TRUE(all.MayDependOn(write));
EXPECT_FALSE(write.MayDependOn(all));
EXPECT_FALSE(all.MayDependOn(read));
EXPECT_TRUE(read.MayDependOn(all));
// None-dependences.
SideEffects none = SideEffects::None();
EXPECT_FALSE(none.MayDependOn(write));
EXPECT_FALSE(write.MayDependOn(none));
EXPECT_FALSE(none.MayDependOn(read));
EXPECT_FALSE(read.MayDependOn(none));
}
void testWriteAndReadDependence(SideEffects write, SideEffects read) {
testWriteAndReadEffects(write, read);
// Dependence only in one direction.
EXPECT_FALSE(write.MayDependOn(read));
EXPECT_TRUE(read.MayDependOn(write));
}
void testNoWriteAndReadDependence(SideEffects write, SideEffects read) {
testWriteAndReadEffects(write, read);
// No dependence in any direction.
EXPECT_FALSE(write.MayDependOn(read));
EXPECT_FALSE(read.MayDependOn(write));
}
//
// Actual tests.
//
TEST(SideEffectsTest, All) {
SideEffects all = SideEffects::All();
EXPECT_TRUE(all.DoesAnyWrite());
EXPECT_TRUE(all.DoesAnyRead());
EXPECT_FALSE(all.DoesNothing());
EXPECT_TRUE(all.DoesAllReadWrite());
}
TEST(SideEffectsTest, None) {
SideEffects none = SideEffects::None();
EXPECT_FALSE(none.DoesAnyWrite());
EXPECT_FALSE(none.DoesAnyRead());
EXPECT_TRUE(none.DoesNothing());
EXPECT_FALSE(none.DoesAllReadWrite());
}
TEST(SideEffectsTest, DependencesAndNoDependences) {
// Apply test to each individual data type.
for (DataType::Type type : kTestTypes) {
// Same data type and access type: proper write/read dep.
testWriteAndReadDependence(
SideEffects::FieldWriteOfType(type, false ),
SideEffects::FieldReadOfType(type, false ));
testWriteAndReadDependence(
SideEffects::ArrayWriteOfType(type),
SideEffects::ArrayReadOfType(type));
// Same data type but different access type: no write/read dep.
testNoWriteAndReadDependence(
SideEffects::FieldWriteOfType(type, false ),
SideEffects::ArrayReadOfType(type));
testNoWriteAndReadDependence(
SideEffects::ArrayWriteOfType(type),
SideEffects::FieldReadOfType(type, false ));
}
}
TEST(SideEffectsTest, NoDependences) {
// Different data type, same access type: no write/read dep.
testNoWriteAndReadDependence(
SideEffects::FieldWriteOfType(DataType::Type::kInt32, false ),
SideEffects::FieldReadOfType(DataType::Type::kFloat64, false ));
testNoWriteAndReadDependence(
SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
// Everything different: no write/read dep.
testNoWriteAndReadDependence(
SideEffects::FieldWriteOfType(DataType::Type::kInt32, false ),
SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
testNoWriteAndReadDependence(
SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
SideEffects::FieldReadOfType(DataType::Type::kFloat64, false ));
}
TEST(SideEffectsTest, VolatileDependences) {
SideEffects volatile_write =
SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile= */ true);
SideEffects any_write =
SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile= */ false);
SideEffects volatile_read =
SideEffects::FieldReadOfType(DataType::Type::kInt8, /* is_volatile= */ true);
SideEffects any_read =
SideEffects::FieldReadOfType(DataType::Type::kInt8, /* is_volatile= */ false);
EXPECT_FALSE(volatile_write.MayDependOn(any_read));
EXPECT_TRUE(any_read.MayDependOn(volatile_write));
EXPECT_TRUE(volatile_write.MayDependOn(any_write));
EXPECT_FALSE(any_write.MayDependOn(volatile_write));
EXPECT_FALSE(volatile_read.MayDependOn(any_read));
EXPECT_TRUE(any_read.MayDependOn(volatile_read));
EXPECT_TRUE(volatile_read.MayDependOn(any_write));
EXPECT_FALSE(any_write.MayDependOn(volatile_read));
}
TEST(SideEffectsTest, SameWidthTypesNoAlias) {
// Type I/F.
testNoWriteAndReadDependence(
SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile= */ false),
SideEffects::FieldReadOfType(DataType::Type::kFloat32, /* is_volatile= */ false));
testNoWriteAndReadDependence(
SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
SideEffects::ArrayReadOfType(DataType::Type::kFloat32));
// Type L/D.
testNoWriteAndReadDependence(
SideEffects::FieldWriteOfType(DataType::Type::kInt64, /* is_volatile= */ false),
SideEffects::FieldReadOfType(DataType::Type::kFloat64, /* is_volatile= */ false));
testNoWriteAndReadDependence(
SideEffects::ArrayWriteOfType(DataType::Type::kInt64),
SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
}
TEST(SideEffectsTest, AllWritesAndReads) {
SideEffects s = SideEffects::None();
// Keep taking the union of different writes and reads.
for (DataType::Type type : kTestTypes) {
s = s.Union (SideEffects::FieldWriteOfType(type, /* is_volatile= */ false));
s = s.Union (SideEffects::ArrayWriteOfType(type));
s = s.Union (SideEffects::FieldReadOfType(type, /* is_volatile= */ false));
s = s.Union (SideEffects::ArrayReadOfType(type));
}
EXPECT_TRUE(s.DoesAllReadWrite());
}
TEST(SideEffectsTest, GC) {
SideEffects can_trigger_gc = SideEffects::CanTriggerGC();
SideEffects depends_on_gc = SideEffects::DependsOnGC();
SideEffects all_changes = SideEffects::AllChanges();
SideEffects all_dependencies = SideEffects::AllDependencies();
EXPECT_TRUE(depends_on_gc.MayDependOn(can_trigger_gc));
EXPECT_TRUE(depends_on_gc.Union (can_trigger_gc).MayDependOn(can_trigger_gc));
EXPECT_FALSE(can_trigger_gc.MayDependOn(depends_on_gc));
EXPECT_TRUE(depends_on_gc.MayDependOn(all_changes));
EXPECT_TRUE(depends_on_gc.Union (can_trigger_gc).MayDependOn(all_changes));
EXPECT_FALSE(can_trigger_gc.MayDependOn(all_changes));
EXPECT_FALSE(can_trigger_gc.MayDependOn(can_trigger_gc));
EXPECT_TRUE(all_changes.Includes(can_trigger_gc));
EXPECT_FALSE(all_changes.Includes(depends_on_gc));
EXPECT_TRUE(all_dependencies.Includes(depends_on_gc));
EXPECT_FALSE(all_dependencies.Includes(can_trigger_gc));
}
TEST(SideEffectsTest, BitStrings) {
EXPECT_STREQ(
"|||||||" ,
SideEffects::None().ToString().c_str());
EXPECT_STREQ(
"|GC|DFJISCBZL|DFJISCBZL|GC|DFJISCBZL|DFJISCBZL|" ,
SideEffects::All().ToString().c_str());
EXPECT_STREQ(
"|||||DFJISCBZL|DFJISCBZL|" ,
SideEffects::AllWrites().ToString().c_str());
EXPECT_STREQ(
"||DFJISCBZL|DFJISCBZL||||" ,
SideEffects::AllReads().ToString().c_str());
EXPECT_STREQ(
"||||||L|" ,
SideEffects::FieldWriteOfType(DataType::Type::kReference, false ).ToString().c_str());
EXPECT_STREQ(
"||DFJISCBZL|DFJISCBZL||DFJISCBZL|DFJISCBZL|" ,
SideEffects::FieldWriteOfType(DataType::Type::kReference, true ).ToString().c_str());
EXPECT_STREQ(
"|||||Z||" ,
SideEffects::ArrayWriteOfType(DataType::Type::kBool).ToString().c_str());
EXPECT_STREQ(
"|||||C||" ,
SideEffects::ArrayWriteOfType(DataType::Type::kUint16).ToString().c_str());
EXPECT_STREQ(
"|||||S||" ,
SideEffects::ArrayWriteOfType(DataType::Type::kInt16).ToString().c_str());
EXPECT_STREQ(
"|||B||||" ,
SideEffects::FieldReadOfType(DataType::Type::kInt8, false ).ToString().c_str());
EXPECT_STREQ(
"||D|||||" ,
SideEffects::ArrayReadOfType(DataType::Type::kFloat64).ToString().c_str());
EXPECT_STREQ(
"||J|||||" ,
SideEffects::ArrayReadOfType(DataType::Type::kInt64).ToString().c_str());
EXPECT_STREQ(
"||F|||||" ,
SideEffects::ArrayReadOfType(DataType::Type::kFloat32).ToString().c_str());
EXPECT_STREQ(
"||I|||||" ,
SideEffects::ArrayReadOfType(DataType::Type::kInt32).ToString().c_str());
SideEffects s = SideEffects::None();
s = s.Union (SideEffects::FieldWriteOfType(DataType::Type::kUint16, /* is_volatile= */ false));
s = s.Union (SideEffects::FieldWriteOfType(DataType::Type::kInt64, /* is_volatile= */ false));
s = s.Union (SideEffects::ArrayWriteOfType(DataType::Type::kInt16));
s = s.Union (SideEffects::FieldReadOfType(DataType::Type::kInt32, /* is_volatile= */ false));
s = s.Union (SideEffects::ArrayReadOfType(DataType::Type::kFloat32));
s = s.Union (SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
EXPECT_STREQ("||DF|I||S|JC|" , s.ToString().c_str());
}
} // namespace art
Messung V0.5 in Prozent C=89 H=88 G=88
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-29)
¤
*© Formatika GbR, Deutschland