From 2db0c81fc8067d73230fcbffc90bd7ad1f9c07b0 Mon Sep 17 00:00:00 2001 From: Nils Maier Date: Tue, 26 Nov 2013 02:59:51 +0100 Subject: Stuff memory holes Padding changes on x86_64: - RequestGroup: 29 -> 5 bytes - DownloadContext: 25 -> 1 bytes - Cookie: 20 -> 4 bytes - Command: 8 -> 0 bytes (affects many derived as well) - HttpRequest: 20 -> 4 bytes - DownloadCommand: 18 -> 2 bytes - TimeBasedCommand: 14 -> 6 bytes - AbstractCommand: 13 -> 5 bytes - HttpSkipResponseCommand: 12 -> 4 bytes - FileEntry: 10 -> 2 bytes - DownloadResult: 15 -> 7 bytes - UriStruct: 12 -> 4 bytes - Piece: 11 -> 3 bytes - BitfieldMan -> 11 -> 3 bytes --- src/AbstractCommand.cc | 35 ++++++++-------- src/AbstractCommand.h | 34 ++++++++-------- src/BitfieldMan.cc | 54 ++++++++++++------------- src/BitfieldMan.h | 20 +++++---- src/Command.cc | 4 +- src/Command.h | 7 +++- src/Cookie.cc | 64 +++++++++++++---------------- src/Cookie.h | 31 +++++--------- src/DownloadCommand.cc | 14 +++---- src/DownloadCommand.h | 17 ++++---- src/DownloadContext.cc | 33 +++++++-------- src/DownloadContext.h | 24 ++++++----- src/DownloadResult.cc | 9 ++--- src/DownloadResult.h | 36 ++++++++--------- src/FileEntry.cc | 23 +++++------ src/FileEntry.h | 30 ++++++++------ src/HttpRequest.cc | 12 +++--- src/HttpRequest.h | 31 +++++++------- src/HttpSkipResponseCommand.cc | 8 ++-- src/HttpSkipResponseCommand.h | 30 +++++++------- src/Piece.cc | 20 +++++---- src/Piece.h | 27 +++++++------ src/RequestGroup.cc | 38 ++++++++--------- src/RequestGroup.h | 92 +++++++++++++++++++++--------------------- src/TimeBasedCommand.cc | 11 +++-- src/TimeBasedCommand.h | 7 ++-- src/uri.cc | 6 +-- src/uri.h | 2 +- 28 files changed, 368 insertions(+), 351 deletions(-) (limited to 'src') diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index a6b58260..5dad881a 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -76,26 +76,29 @@ namespace aria2 { -AbstractCommand::AbstractCommand -(cuid_t cuid, - const std::shared_ptr& req, - const std::shared_ptr& fileEntry, - RequestGroup* requestGroup, - DownloadEngine* e, - const std::shared_ptr& s, - const std::shared_ptr& socketRecvBuffer, - bool incNumConnection) - : Command(cuid), checkPoint_(global::wallclock()), - timeout_(requestGroup->getTimeout()), - requestGroup_(requestGroup), - req_(req), fileEntry_(fileEntry), e_(e), socket_(s), +AbstractCommand::AbstractCommand(cuid_t cuid, + const std::shared_ptr& req, + const std::shared_ptr& fileEntry, + RequestGroup* requestGroup, DownloadEngine* e, + const std::shared_ptr& s, + const std::shared_ptr& socketRecvBuffer, + bool incNumConnection) + : Command(cuid), + req_(req), + fileEntry_(fileEntry), + socket_(s), socketRecvBuffer_(socketRecvBuffer), #ifdef ENABLE_ASYNC_DNS asyncNameResolverMan_(make_unique()), #endif // ENABLE_ASYNC_DNS - checkSocketIsReadable_(false), checkSocketIsWritable_(false), - incNumConnection_(incNumConnection), - serverStatTimer_(global::wallclock()) + requestGroup_(requestGroup), + e_(e), + checkPoint_(global::wallclock()), + serverStatTimer_(global::wallclock()), + timeout_(requestGroup->getTimeout()), + checkSocketIsReadable_(false), + checkSocketIsWritable_(false), + incNumConnection_(incNumConnection) { if(socket_ && socket_->isOpen()) { setReadCheckSocket(socket_); diff --git a/src/AbstractCommand.h b/src/AbstractCommand.h index 23fb4950..7f6c9429 100644 --- a/src/AbstractCommand.h +++ b/src/AbstractCommand.h @@ -64,31 +64,34 @@ class AsyncNameResolverMan; class AbstractCommand : public Command { private: - Timer checkPoint_; - time_t timeout_; - - RequestGroup* requestGroup_; std::shared_ptr req_; std::shared_ptr fileEntry_; - DownloadEngine* e_; std::shared_ptr socket_; std::shared_ptr socketRecvBuffer_; - std::vector > segments_; + std::shared_ptr readCheckTarget_; + std::shared_ptr writeCheckTarget_; #ifdef ENABLE_ASYNC_DNS std::unique_ptr asyncNameResolverMan_; #endif // ENABLE_ASYNC_DNS + RequestGroup* requestGroup_; + DownloadEngine* e_; + + std::vector > segments_; + + Timer checkPoint_; + Timer serverStatTimer_; + time_t timeout_; + bool checkSocketIsReadable_; bool checkSocketIsWritable_; - std::shared_ptr readCheckTarget_; - std::shared_ptr writeCheckTarget_; bool incNumConnection_; - Timer serverStatTimer_; int32_t calculateMinSplitSize() const; void useFasterRequest(const std::shared_ptr& fasterRequest); + public: RequestGroup* getRequestGroup() const { @@ -234,13 +237,12 @@ protected: } public: - AbstractCommand - (cuid_t cuid, const std::shared_ptr& req, - const std::shared_ptr& fileEntry, - RequestGroup* requestGroup, DownloadEngine* e, - const std::shared_ptr& s = nullptr, - const std::shared_ptr& socketRecvBuffer = nullptr, - bool incNumConnection = true); + AbstractCommand(cuid_t cuid, const std::shared_ptr& req, + const std::shared_ptr& fileEntry, + RequestGroup* requestGroup, DownloadEngine* e, + const std::shared_ptr& s = nullptr, + const std::shared_ptr& socketRecvBuffer = nullptr, + bool incNumConnection = true); virtual ~AbstractCommand(); virtual bool execute() CXX11_OVERRIDE; diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc index 4cfc9994..c1904205 100644 --- a/src/BitfieldMan.cc +++ b/src/BitfieldMan.cc @@ -45,19 +45,19 @@ using namespace aria2::expr; namespace aria2 { BitfieldMan::BitfieldMan(int32_t blockLength, int64_t totalLength) - :blockLength_(blockLength), - totalLength_(totalLength), - bitfieldLength_(0), - blocks_(0), - filterEnabled_(false), - bitfield_(nullptr), - useBitfield_(nullptr), - filterBitfield_(nullptr), - cachedNumMissingBlock_(0), - cachedNumFilteredBlock_(0), - cachedCompletedLength_(0), - cachedFilteredCompletedLength_(0), - cachedFilteredTotalLength_(0) + : totalLength_(totalLength), + cachedCompletedLength_(0), + cachedFilteredCompletedLength_(0), + cachedFilteredTotalLength_(0), + bitfield_(nullptr), + useBitfield_(nullptr), + filterBitfield_(nullptr), + bitfieldLength_(0), + cachedNumMissingBlock_(0), + cachedNumFilteredBlock_(0), + blocks_(0), + blockLength_(blockLength), + filterEnabled_(false) { if(blockLength_ > 0 && totalLength_ > 0) { blocks_ = (totalLength_+blockLength_-1)/blockLength_; @@ -71,19 +71,19 @@ BitfieldMan::BitfieldMan(int32_t blockLength, int64_t totalLength) } BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan) - :blockLength_(bitfieldMan.blockLength_), - totalLength_(bitfieldMan.totalLength_), - bitfieldLength_(bitfieldMan.bitfieldLength_), - blocks_(bitfieldMan.blocks_), - filterEnabled_(bitfieldMan.filterEnabled_), - bitfield_(new unsigned char[bitfieldLength_]), - useBitfield_(new unsigned char[bitfieldLength_]), - filterBitfield_(nullptr), - cachedNumMissingBlock_(0), - cachedNumFilteredBlock_(0), - cachedCompletedLength_(0), - cachedFilteredCompletedLength_(0), - cachedFilteredTotalLength_(0) + : totalLength_(bitfieldMan.totalLength_), + cachedCompletedLength_(0), + cachedFilteredCompletedLength_(0), + cachedFilteredTotalLength_(0), + bitfield_(new unsigned char[bitfieldMan.bitfieldLength_]), + useBitfield_(new unsigned char[bitfieldMan.bitfieldLength_]), + filterBitfield_(nullptr), + bitfieldLength_(bitfieldMan.bitfieldLength_), + cachedNumMissingBlock_(0), + cachedNumFilteredBlock_(0), + blocks_(bitfieldMan.blocks_), + blockLength_(bitfieldMan.blockLength_), + filterEnabled_(bitfieldMan.filterEnabled_) { memcpy(bitfield_, bitfieldMan.bitfield_, bitfieldLength_); memcpy(useBitfield_, bitfieldMan.useBitfield_, bitfieldLength_); @@ -97,8 +97,8 @@ BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan) BitfieldMan& BitfieldMan::operator=(const BitfieldMan& bitfieldMan) { if(this != &bitfieldMan) { - blockLength_ = bitfieldMan.blockLength_; totalLength_ = bitfieldMan.totalLength_; + blockLength_ = bitfieldMan.blockLength_; blocks_ = bitfieldMan.blocks_; bitfieldLength_ = bitfieldMan.bitfieldLength_; filterEnabled_ = bitfieldMan.filterEnabled_; diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h index fa0ac09f..60e44547 100644 --- a/src/BitfieldMan.h +++ b/src/BitfieldMan.h @@ -43,21 +43,23 @@ namespace aria2 { class BitfieldMan { private: - int32_t blockLength_; int64_t totalLength_; - size_t bitfieldLength_; - size_t blocks_; - bool filterEnabled_; + int64_t cachedCompletedLength_; + int64_t cachedFilteredCompletedLength_; + int64_t cachedFilteredTotalLength_; + unsigned char* bitfield_; unsigned char* useBitfield_; unsigned char* filterBitfield_; - // for caching + size_t bitfieldLength_; size_t cachedNumMissingBlock_; size_t cachedNumFilteredBlock_; - int64_t cachedCompletedLength_; - int64_t cachedFilteredCompletedLength_; - int64_t cachedFilteredTotalLength_; + size_t blocks_; + + int32_t blockLength_; + + bool filterEnabled_; bool setBitInternal(unsigned char* bitfield, size_t index, bool on); bool setFilterBit(size_t index); @@ -70,6 +72,7 @@ private: // If filterBitfield_ is 0, allocate bitfieldLength_ bytes to it and // set 0 to all bytes. void ensureFilterBitfield(); + public: // [startIndex, endIndex) struct Range { @@ -81,6 +84,7 @@ public: bool operator<(const Range& range) const; bool operator==(const Range& range) const; }; + public: BitfieldMan(int32_t blockLength, int64_t totalLength); BitfieldMan(const BitfieldMan& bitfieldMan); diff --git a/src/Command.cc b/src/Command.cc index 82db3178..b9e236b7 100644 --- a/src/Command.cc +++ b/src/Command.cc @@ -38,8 +38,8 @@ namespace aria2 { Command::Command(cuid_t cuid) - : status_(STATUS_INACTIVE), - cuid_(cuid), + : cuid_(cuid), + status_(STATUS_INACTIVE), readEvent_(false), writeEvent_(false), errorEvent_(false), diff --git a/src/Command.h b/src/Command.h index a164661d..07d4de6d 100644 --- a/src/Command.h +++ b/src/Command.h @@ -50,15 +50,17 @@ public: STATUS_REALTIME, STATUS_ONESHOT_REALTIME }; -private: - STATUS status_; +private: cuid_t cuid_; + STATUS status_; + bool readEvent_; bool writeEvent_; bool errorEvent_; bool hupEvent_; + protected: bool readEventEnabled() const { @@ -79,6 +81,7 @@ protected: { return hupEvent_; } + public: Command(cuid_t cuid); diff --git a/src/Cookie.cc b/src/Cookie.cc index 2c8b881e..7da196a1 100644 --- a/src/Cookie.cc +++ b/src/Cookie.cc @@ -42,37 +42,32 @@ namespace aria2 { -Cookie::Cookie -(std::string name, - std::string value, - time_t expiryTime, - bool persistent, - std::string domain, - bool hostOnly, - std::string path, - bool secure, - bool httpOnly, - time_t creationTime): - name_(std::move(name)), - value_(std::move(value)), - expiryTime_(expiryTime), - persistent_(persistent), - domain_(std::move(domain)), - hostOnly_(hostOnly), - path_(std::move(path)), - secure_(secure), - httpOnly_(httpOnly), - creationTime_(creationTime), - lastAccessTime_(creationTime) {} - -Cookie::Cookie(): - expiryTime_(0), - persistent_(false), - hostOnly_(false), - secure_(false), - httpOnly_(false), - creationTime_(0), - lastAccessTime_(0) {} +Cookie::Cookie(std::string name, std::string value, time_t expiryTime, + bool persistent, std::string domain, bool hostOnly, + std::string path, bool secure, bool httpOnly, + time_t creationTime) + : expiryTime_(expiryTime), + creationTime_(creationTime), + lastAccessTime_(creationTime), + name_(std::move(name)), + value_(std::move(value)), + domain_(std::move(domain)), + path_(std::move(path)), + persistent_(persistent), + hostOnly_(hostOnly), + secure_(secure), + httpOnly_(httpOnly) +{} + +Cookie::Cookie() + : expiryTime_(0), + creationTime_(0), + lastAccessTime_(0), + persistent_(false), + hostOnly_(false), + secure_(false), + httpOnly_(false) +{} std::string Cookie::toString() const { @@ -82,10 +77,9 @@ std::string Cookie::toString() const return s; } -bool Cookie::match -(const std::string& requestHost, - const std::string& requestPath, - time_t date, bool secure) const +bool Cookie::match(const std::string& requestHost, + const std::string& requestPath, + time_t date, bool secure) const { if((secure_ && !secure) || isExpired(date) || !cookie::pathMatch(requestPath, path_)) { diff --git a/src/Cookie.h b/src/Cookie.h index d97ddaeb..aa711724 100644 --- a/src/Cookie.h +++ b/src/Cookie.h @@ -45,40 +45,31 @@ namespace aria2 { class Cookie { private: + time_t expiryTime_; + time_t creationTime_; + time_t lastAccessTime_; std::string name_; std::string value_; - time_t expiryTime_; + std::string domain_; + std::string path_; // If persistent_ is false, this is a session scope cookie and it is // never expired during session. So isExpired() always returns // false. bool persistent_; - std::string domain_; bool hostOnly_; - std::string path_; bool secure_; bool httpOnly_; - time_t creationTime_; - time_t lastAccessTime_; + public: Cookie(); - - Cookie - (std::string name, - std::string value, - time_t expiryTime, - bool persistent, - std::string domain, - bool hostOnly, - std::string path, - bool secure, - bool httpOnly, - time_t creationTime); + Cookie(std::string name, std::string value, time_t expiryTime, + bool persistent, std::string domain, bool hostOnly, std::string path, + bool secure, bool httpOnly, time_t creationTime); std::string toString() const; - bool match - (const std::string& requestHost, const std::string& requestPath, - time_t date, bool secure) const; + bool match(const std::string& requestHost, const std::string& requestPath, + time_t date, bool secure) const; bool operator==(const Cookie& cookie) const; diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc index 4665efa8..f1563cfe 100644 --- a/src/DownloadCommand.cc +++ b/src/DownloadCommand.cc @@ -79,14 +79,12 @@ namespace { const size_t BUFSIZE = 16*1024; } // namespace -DownloadCommand::DownloadCommand -(cuid_t cuid, - const std::shared_ptr& req, - const std::shared_ptr& fileEntry, - RequestGroup* requestGroup, - DownloadEngine* e, - const std::shared_ptr& s, - const std::shared_ptr& socketRecvBuffer) +DownloadCommand::DownloadCommand(cuid_t cuid, + const std::shared_ptr& req, + const std::shared_ptr& fileEntry, + RequestGroup* requestGroup, DownloadEngine* e, + const std::shared_ptr& s, + const std::shared_ptr& socketRecvBuffer) : AbstractCommand(cuid, req, fileEntry, requestGroup, e, s, socketRecvBuffer), startupIdleTime_(10), lowestDownloadSpeedLimit_(0), diff --git a/src/DownloadCommand.h b/src/DownloadCommand.h index 02520c2c..ddb87da1 100644 --- a/src/DownloadCommand.h +++ b/src/DownloadCommand.h @@ -49,18 +49,22 @@ class MessageDigest; class DownloadCommand : public AbstractCommand { private: - time_t startupIdleTime_; - int lowestDownloadSpeedLimit_; std::shared_ptr peerStat_; - bool pieceHashValidationEnabled_; + std::unique_ptr streamFilter_; #ifdef ENABLE_MESSAGE_DIGEST - std::unique_ptr messageDigest_; - #endif // ENABLE_MESSAGE_DIGEST + time_t startupIdleTime_; + + int lowestDownloadSpeedLimit_; + + bool pieceHashValidationEnabled_; + + bool sinkFilterOnly_; + void validatePieceHash(const std::shared_ptr& segment, const std::string& expectedPieceHash, const std::string& actualPieceHash); @@ -69,9 +73,6 @@ private: void completeSegment(cuid_t cuid, const std::shared_ptr& segment); - std::unique_ptr streamFilter_; - - bool sinkFilterOnly_; protected: virtual bool executeInternal() CXX11_OVERRIDE; diff --git a/src/DownloadContext.cc b/src/DownloadContext.cc index cb945663..819a51cd 100644 --- a/src/DownloadContext.cc +++ b/src/DownloadContext.cc @@ -47,25 +47,26 @@ namespace aria2 { -DownloadContext::DownloadContext(): - pieceLength_(0), - checksumVerified_(false), - knowsTotalLength_(true), - ownerRequestGroup_(nullptr), - attrs_(MAX_CTX_ATTR), - downloadStopTime_(0), - acceptMetalink_(true) {} +DownloadContext::DownloadContext() + : ownerRequestGroup_(nullptr), + attrs_(MAX_CTX_ATTR), + downloadStopTime_(0), + pieceLength_(0), + checksumVerified_(false), + knowsTotalLength_(true), + acceptMetalink_(true) +{} DownloadContext::DownloadContext(int32_t pieceLength, int64_t totalLength, - const std::string& path): - pieceLength_(pieceLength), - checksumVerified_(false), - knowsTotalLength_(true), - ownerRequestGroup_(nullptr), - attrs_(MAX_CTX_ATTR), - downloadStopTime_(0), - acceptMetalink_(true) + const std::string& path) + : ownerRequestGroup_(nullptr), + attrs_(MAX_CTX_ATTR), + downloadStopTime_(0), + pieceLength_(pieceLength), + checksumVerified_(false), + knowsTotalLength_(true), + acceptMetalink_(true) { std::shared_ptr fileEntry(new FileEntry(path, totalLength, 0)); fileEntries_.push_back(fileEntry); diff --git a/src/DownloadContext.h b/src/DownloadContext.h index fe1e665a..310bcccc 100644 --- a/src/DownloadContext.h +++ b/src/DownloadContext.h @@ -58,11 +58,19 @@ class FileEntry; class DownloadContext { private: + std::unique_ptr signature_; + + RequestGroup* ownerRequestGroup_; + + std::vector > attrs_; + std::vector > fileEntries_; std::vector pieceHashes_; - int32_t pieceLength_; + NetStat netStat_; + + Timer downloadStopTime_; std::string pieceHashType_; @@ -70,24 +78,18 @@ private: std::string hashType_; - bool checksumVerified_; - std::string basePath_; - bool knowsTotalLength_; - - RequestGroup* ownerRequestGroup_; - - std::vector > attrs_; + int32_t pieceLength_; - NetStat netStat_; + bool checksumVerified_; - Timer downloadStopTime_; + bool knowsTotalLength_; - std::unique_ptr signature_; // This member variable is required to avoid to use parse Metalink // (including both Metalink XML and Metalink/HTTP) twice. bool acceptMetalink_; + public: DownloadContext(); diff --git a/src/DownloadResult.cc b/src/DownloadResult.cc index 49cba379..faa9b1c0 100644 --- a/src/DownloadResult.cc +++ b/src/DownloadResult.cc @@ -40,17 +40,16 @@ namespace aria2 { DownloadResult::DownloadResult() - : gid(nullptr), - inMemoryDownload(false), + : belongsTo(0), sessionDownloadLength(0), sessionTime(0), - result(error_code::UNDEFINED), - belongsTo(0), totalLength(0), completedLength(0), uploadLength(0), + numPieces(0), pieceLength(0), - numPieces(0) + result(error_code::UNDEFINED), + inMemoryDownload(false) {} DownloadResult::~DownloadResult() {} diff --git a/src/DownloadResult.h b/src/DownloadResult.h index 729e97d2..949c7c84 100644 --- a/src/DownloadResult.h +++ b/src/DownloadResult.h @@ -54,46 +54,46 @@ class MetadataInfo; struct DownloadResult { - std::shared_ptr gid; - - std::vector > fileEntries; - - bool inMemoryDownload; + // This field contains GID. See comment in + // RequestGroup.cc::belongsToGID_. + a2_gid_t belongsTo; uint64_t sessionDownloadLength; // milliseconds int64_t sessionTime; - error_code::Value result; + int64_t totalLength; - // This field contains GIDs. See comment in - // RequestGroup.cc::followedByGIDs_. - std::vector followedBy; + int64_t completedLength; - // This field contains GID. See comment in - // RequestGroup.cc::belongsToGID_. - a2_gid_t belongsTo; + int64_t uploadLength; + + std::shared_ptr gid; std::shared_ptr