15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a unittest set for type_profiler. It is independent from other 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tests and executed manually like allocator_unittests since type_profiler_map 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used in type_profiler is a singleton (like TCMalloc's heap-profiler), and 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it requires RTTI and different compiling/linking options from others 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It tests that the profiler doesn't fail in suspicous cases. For example, 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'new' is not profiled, but 'delete' for the created object is profiled. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TYPE_PROFILING) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/type_profiler.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/type_profiler_control.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/type_profiler_tcmalloc.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace type_profiler { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TypeProfilerTest : public testing::Test { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TypeProfilerTest() {} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetInterceptFunctions() { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptFunctions::SetFunctions(NewInterceptForTCMalloc, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteInterceptForTCMalloc); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetInterceptFunctions() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptFunctions::ResetFunctions(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetUp() { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInterceptFunctions(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TearDown() { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetInterceptFunctions(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kDummyArraySize; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const void* const kConstNull; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TypeProfilerTest); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t TypeProfilerTest::kDummyArraySize = 10; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const void* const TypeProfilerTest::kConstNull = static_cast<const void*>(NULL); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TypeProfilerTest, TestNormalProfiling) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* dummy = new int(48); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::type_info* type; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(kConstNull, type); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_STREQ(typeid(int).name(), type->name()); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete dummy; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kConstNull, type); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TypeProfilerTest, TestNormalArrayProfiling) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* dummy = new int[kDummyArraySize]; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::type_info* type; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(kConstNull, type); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For an array, the profiler remembers its base type. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_STREQ(typeid(int).name(), type->name()); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] dummy; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kConstNull, type); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TypeProfilerTest, TestRepeatedNewAndDelete) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *dummy[kDummyArraySize]; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::type_info* type; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kDummyArraySize; ++i) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dummy[i] = new int(i); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kDummyArraySize; ++i) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy[i]); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(kConstNull, type); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_STREQ(typeid(int).name(), type->name()); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kDummyArraySize; ++i) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete dummy[i]; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy[i]); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(kConstNull, type); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TypeProfilerTest, TestMultipleNewWithDroppingDelete) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t large_size = 256 * 1024; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* dummy_char = new char[large_size / sizeof(*dummy_char)]; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::type_info* type; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy_char); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(kConstNull, type); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_STREQ(typeid(char).name(), type->name()); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call "::operator delete" directly to drop __op_delete_intercept__. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::operator delete[](dummy_char); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy_char); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(kConstNull, type); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_STREQ(typeid(char).name(), type->name()); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocates a little different size. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* dummy_int = new int[large_size / sizeof(*dummy_int) - 1]; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We expect that tcmalloc returns the same address for these large (over 32k) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allocation calls. It usually happens, but maybe probablistic. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(static_cast<void*>(dummy_char), static_cast<void*>(dummy_int)) << 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "two new (malloc) calls didn't return the same address; retry it."; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy_int); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(kConstNull, type); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_STREQ(typeid(int).name(), type->name()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] dummy_int; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy_int); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kConstNull, type); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TypeProfilerTest, TestProfileDeleteWithoutProfiledNew) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'dummy' should be new'ed in this test before intercept functions are set. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetInterceptFunctions(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* dummy = new int(48); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::type_info* type; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set intercept functions again after 'dummy' is new'ed. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInterceptFunctions(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete dummy; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kConstNull, type); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetInterceptFunctions(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TypeProfilerTest, TestProfileNewWithoutProfiledDelete) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* dummy = new int(48); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::type_info* type; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Controller::IsProfiling()); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop profiling before deleting 'dummy'. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Controller::Stop(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(Controller::IsProfiling()); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete dummy; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: We accept that a profile entry remains when a profiled object is 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deleted after Controller::Stop(). 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = LookupType(dummy); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(kConstNull, type); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_STREQ(typeid(int).name(), type->name()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Controller::Restart(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Controller::IsProfiling()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove manually since 'dummy' is not removed from type_profiler_map. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EraseType(dummy); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace type_profiler 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(TYPE_PROFILING) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char** argv) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::InitGoogleTest(&argc, argv); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RUN_ALL_TESTS(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 190