[PATCH] RFC: fail-fast iterators for DenseMap
Duncan P. N. Exon Smith
dexonsmith at apple.com
Sun Mar 1 08:48:35 PST 2015
> On 2015 Feb 28, at 23:46, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:
>
> Address Chandler's review.
>
> - no "ADT" in the file or class names.
> - changed the vocabulary to "Handle" and "Host"
> - suffixed the class names with "Base" and change the DenseMap implementation to use inheritance over composition.
> - handled the NDEBUG-only-ness directly in the header file. Once this was locked down, I could not justify the additional complexity from the template specialization, so I removed that too.
>
>
> http://reviews.llvm.org/D7931
This is much cleaner than the original implementation. Nice! I have a
few nitpicks:
> Index: include/llvm/ADT/EpochTracker.h
> ===================================================================
> --- /dev/null
> +++ include/llvm/ADT/EpochTracker.h
> @@ -0,0 +1,65 @@
> +//===- llvm/ADT/EpochTracker.h - ADT epoch tracking-*- C++ -*--------------===//
Missing a space here ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
Also, don't we usually dump the C++ mode at the end of the line?
//===- llvm/ADT/EpochTracker.h - ADT epoch tracking -------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file defines the EpochTrackerHostBase and EpochTrackerHandleBase
> +// classes. These can be used to write iterators that are fail-fast when LLVM
> +// is built with asserts enabled.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_ADT_EPOCH_TRACKER_H
> +#define LLVM_ADT_EPOCH_TRACKER_H
> +
> +namespace llvm {
> +
> +#ifdef NDEBUG
> +
> +// These classes are no-op in a build without asserts.
This should probably just be part of the class documentation for each
class.
> +
> +class EpochTrackerHostBase {
I think the NDEBUG should go here (inside the class), and you should add
some short doxygen to the class.
> +public:
> + void bumpEpoch() {}
> +};
> +
> +class EpochTrackerHandleBase {
(You'd obviously need a separate NDEBUG here.)
> +public:
> + EpochTrackerHandleBase(const EpochTrackerHostBase *) {}
I'd probably mark this `explicit`.
I think you might need this as well:
EpochTrackerHandleBase() {}
> + bool isHandleInSync() { return true; }
> +};
> +
> +#else
> +
> +class EpochTrackerHostBase {
> + uint64_t Epoch;
> +
> +public:
> + EpochTrackerHostBase() : Epoch(0){};
This semi-colon ~~~~~~~~~~~~~~~~~~~~~~~~^ will cause problems with some
compilers. Also, `clang-format` would put a space before the `{}`.
> + void bumpEpoch() { Epoch++; }
Not that it really matters here, but `++Epoch` is canonical.
> + ~EpochTrackerHostBase() { bumpEpoch(); }
Is this to catch use-after-frees? Might be worth a doxygen comment.
> + friend class EpochTrackerHandleBase;
> +};
> +
> +class EpochTrackerHandleBase {
> + const uint64_t *HostEpochAddress;
> + uint64_t EpochAtCreation;
> +
> +public:
> + EpochTrackerHandleBase() : HostEpochAddress(nullptr), EpochAtCreation(-1) {}
I'd prefer `UINT64_MAX` over `-1` here.
> +
> + EpochTrackerHandleBase(const EpochTrackerHostBase *Host)
> + : HostEpochAddress(&Host->Epoch), EpochAtCreation(Host->Epoch) {}
(This should also be `explicit` if you change the NDEBUG version.)
> +
> + bool isHandleInSync() const { return *HostEpochAddress == EpochAtCreation; }
> +};
> +
> +#endif // !defined(NDEBUG)
> +
> +} // namespace llvm
> +
> +#endif
More information about the llvm-commits
mailing list