This is an archive of the discontinued LLVM Phabricator instance.

[scudo][standalone] Add bytemap classes
ClosedPublic

Authored by cryptoad on Feb 27 2019, 9:11 AM.

Details

Summary

The bytemap classes will be used by the primary32 allocator to associate
classes with memory regions. It's similar to the sanitizer_common one
except for the fact that the base (level1) maps are mapped instead of
being static to reduce the memory footprint of an uninitialized allocator.

Diff Detail

Event Timeline

cryptoad created this revision.Feb 27 2019, 9:11 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptFeb 27 2019, 9:11 AM
Herald added subscribers: Restricted Project, jfb, delcypher, mgorny. · View Herald Transcript
vitalybuka accepted this revision.Feb 27 2019, 11:10 AM
This revision is now accepted and ready to land.Feb 27 2019, 11:10 AM
morehouse added inline comments.Feb 27 2019, 11:22 AM
lib/scudo/standalone/bytemap.h
23

Having two init functions is a little confusing. Would it make more sense to have a constexpr constructor and a single init() function?

lib/scudo/standalone/tests/bytemap_test.cc
15

Tests for FlatByteMap?

cryptoad updated this revision to Diff 188601.Feb 27 2019, 12:32 PM
cryptoad marked an inline comment as done.

Adding test for the flat bytemap, reorganzing the existing twolevel one.

cryptoad added inline comments.Mar 1 2019, 8:28 AM
lib/scudo/standalone/bytemap.h
23

With this I followed the way it was done in sanitizer_common with an init function that would skip the zero initialization if not needed (most our structures are either mapped or static). Would you have an example of what you are suggesting, I am not sure I fully understand how to organize it?

morehouse added inline comments.Mar 1 2019, 9:43 AM
lib/scudo/standalone/bytemap.h
23

Essentially, make the zero-initialization explicit in the constexpr constructor, and then do all dynamic initialization in init.

class FlatByteMap {
  constexpr FlatByteMap() : Map(nullptr) {}
  void init() {
    Map = reinterpret_cast<u8 *>(map(nullptr, Size, "scudo:bytemap"));
  }
};

class TwoLevelByteMap {
  constexpr TwoLevelByteMap() : Level1Map(nullptr), Mutex{} {}
  void init() {
    Level1Map = reinterpret_cast<atomic_uptr *>(
        map(nullptr, sizeof(atomic_uptr) * Level1Size, "scudo:bytemap"));
  }
};

The constexpr constructor will initialize any statics / globals at compile time while still working at runtime for non-static instantiations. Then the call to init completes any dynamic initialization required.

morehouse added inline comments.Mar 1 2019, 9:46 AM
lib/scudo/standalone/bytemap.h
23

The linker-init function will work fine, but since we're reimplementing much of sanitizer_common for Scudo now, maybe it's a good opportunity to modernize a bit.

morehouse added inline comments.Mar 1 2019, 10:01 AM
lib/scudo/standalone/bytemap.h
23

You'll probably also need to refactor StaticSpinMutex to use a constexpr constructor for initialization. In fact, we could probably completely remove StaticSpinMutex and just give SpinMutex a constexpr constructor.

class SpinMutex {
  constexpr SpinMutex() : State{} {}
};

Then SpinMutex can be used as either global or local.

cryptoad marked an inline comment as done.Mar 4 2019, 1:00 PM
cryptoad added inline comments.
lib/scudo/standalone/bytemap.h
23

I went into the rabbit hole of changing those and started hitting issues along the way (with __thread).
If that's Ok with you I'd like to land this in it's current shape and revisit that later.

morehouse accepted this revision.Mar 4 2019, 1:31 PM
morehouse added inline comments.
lib/scudo/standalone/bytemap.h
23

SGTM

This revision was automatically updated to reflect the committed changes.