From d230b5fdd3722564c2ddd7186d60749932324006 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 9 Jul 2019 00:54:53 -0400 Subject: [PATCH] packagefs: Use object caches for the most used node classes. Slab statistics from KDL show that on a stock nightly image (i.e. no additional packages besides the standards installed) there are 43848 *objects* (not bytes) in the PackageNodeAttribute cache, and 25090 in the PackageFile cache, so this seems more than worth it. The last commit seems to reduce memory usage at boot by about 1%, this commit seems to not affect it at all; but it is a significant performance optimization and on systems with more packages installed the effect may be very noticeable. Change-Id: I676a642ed6003f82b14396e1f02684575d899362 --- .../packagefs/package/Package.cpp | 6 ++-- .../packagefs/package/PackageDirectory.cpp | 5 +++ .../packagefs/package/PackageDirectory.h | 3 ++ .../packagefs/package/PackageFile.cpp | 7 ++++ .../packagefs/package/PackageFile.h | 3 ++ .../package/PackageNodeAttribute.cpp | 5 +++ .../packagefs/package/PackageNodeAttribute.h | 3 ++ .../file_systems/packagefs/util/ClassCache.h | 35 +++++++++++++++++++ 8 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 src/add-ons/kernel/file_systems/packagefs/util/ClassCache.h diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp index a5ffa4783b..bcb34e18a6 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp @@ -140,7 +140,7 @@ struct Package::LoaderContentHandler : BPackageContentHandler { PackageNode* node; if (S_ISREG(mode)) { // file - node = new(std::nothrow) PackageFile(fPackage, mode, + node = new PackageFile(fPackage, mode, PackageData(entry->Data())); } else if (S_ISLNK(mode)) { // symlink @@ -157,7 +157,7 @@ struct Package::LoaderContentHandler : BPackageContentHandler { node = symlink; } else if (S_ISDIR(mode)) { // directory - node = new(std::nothrow) PackageDirectory(fPackage, mode); + node = new PackageDirectory(fPackage, mode); } else RETURN_ERROR(B_BAD_DATA); @@ -201,7 +201,7 @@ struct Package::LoaderContentHandler : BPackageContentHandler { if (!name.SetTo(attribute->Name())) RETURN_ERROR(B_NO_MEMORY); - PackageNodeAttribute* nodeAttribute = new(std::nothrow) + PackageNodeAttribute* nodeAttribute = new PackageNodeAttribute(attribute->Type(), PackageData(attribute->Data())); if (nodeAttribute == NULL) diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.cpp index 916c42decd..9a51d9f7f3 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.cpp @@ -7,6 +7,11 @@ #include "PackageDirectory.h" #include "Package.h" +#include "ClassCache.h" + + +CLASS_CACHE(PackageDirectory); + PackageDirectory::PackageDirectory(Package* package, mode_t mode) : diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.h b/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.h index d851ae3ded..70f2d49f24 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.h @@ -14,6 +14,9 @@ class PackageDirectory : public PackageNode, public DoublyLinkedListLinkImpl { public: + static void* operator new(size_t size); + static void operator delete(void* block); + PackageDirectory(Package* package, mode_t mode); virtual ~PackageDirectory(); diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.cpp b/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.cpp index dce9c7613c..477c955445 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.cpp @@ -19,12 +19,19 @@ #include #include "DebugSupport.h" +#include "ClassCache.h" #include "Package.h" using namespace BPackageKit::BHPKG; +// #pragma mark - class cache + + +CLASS_CACHE(PackageFile); + + // #pragma mark - DataAccessor diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.h b/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.h index a59fc2d396..aea4a0b7a6 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.h @@ -12,6 +12,9 @@ class PackageFile : public PackageLeafNode { public: + static void* operator new(size_t size); + static void operator delete(void* block); + PackageFile(Package* package, mode_t mode, const PackageData& data); virtual ~PackageFile(); diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp index 713d85a6c1..d7caa92ed4 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp @@ -9,6 +9,11 @@ #include #include +#include "ClassCache.h" + + +CLASS_CACHE(PackageNodeAttribute); + PackageNodeAttribute::PackageNodeAttribute(uint32 type, const PackageData& data) diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h index af01f85652..6404eb53c7 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h @@ -19,6 +19,9 @@ class PackageNode; class PackageNodeAttribute : public DoublyLinkedListLinkImpl { public: + static void* operator new(size_t size); + static void operator delete(void* block); + PackageNodeAttribute(uint32 type, const PackageData& data); ~PackageNodeAttribute(); diff --git a/src/add-ons/kernel/file_systems/packagefs/util/ClassCache.h b/src/add-ons/kernel/file_systems/packagefs/util/ClassCache.h new file mode 100644 index 0000000000..e8cad806b5 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/ClassCache.h @@ -0,0 +1,35 @@ +/* + * Copyright 2019, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef CLASSCACHE_H +#define CLASSCACHE_H + + +#include + + +#define CLASS_CACHE(CLASS) \ + static object_cache* s##CLASS##Cache = NULL; \ + \ + void* \ + CLASS::operator new(size_t size) \ + { \ + if (size != sizeof(CLASS)) \ + panic("unexpected size passed to operator new!"); \ + if (s##CLASS##Cache == NULL) { \ + s##CLASS##Cache = create_object_cache("packagefs " #CLASS "s", \ + sizeof(CLASS), 8, NULL, NULL, NULL); \ + } \ + \ + return object_cache_alloc(s##CLASS##Cache, 0); \ + } \ + \ + void \ + CLASS::operator delete(void* block) \ + { \ + object_cache_free(s##CLASS##Cache, block, 0); \ + } + + +#endif // CLASSCACHE_H