[Lldb-commits] [PATCH] D77765: Fix incorrect L1 inferior memory cache flushing
Greg Clayton via Phabricator via lldb-commits
lldb-commits at lists.llvm.org
Wed Apr 8 21:02:56 PDT 2020
clayborg added a comment.
I am not a pro at the gtest stuff, but this was very hard to follow and figure out what these tests are doing.
================
Comment at: lldb/source/Target/Memory.cpp:23-24
// MemoryCache constructor
-MemoryCache::MemoryCache(Process &process)
+MemoryCache::MemoryCache(MemoryFromInferiorReader &reader,
+ uint64_t cache_line_size)
: m_mutex(), m_L1_cache(), m_L2_cache(), m_invalid_ranges(),
----------------
Might be cleaner to add getting the cache line size from the MemoryFromInferiorReader as a second virtual function. This would avoid having to add the extra parameter here and to the clear method.
================
Comment at: lldb/source/Target/Memory.cpp:31
-void MemoryCache::Clear(bool clear_invalid_ranges) {
+void MemoryCache::Clear(uint64_t cache_line_size, bool clear_invalid_ranges) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
----------------
remove "cache_line_size" if we add a new virtual function to MemoryFromInferiorReader
================
Comment at: lldb/source/Target/Memory.cpp:37
m_invalid_ranges.Clear();
- m_L2_cache_line_byte_size = m_process.GetMemoryCacheLineSize();
+ m_L2_cache_line_byte_size = cache_line_size;
}
----------------
Change to:
```
m_L2_cache_line_byte_size = m_reader.GetCacheLineSize();
```
if we add virtual function to MemoryFromInferiorReader
================
Comment at: lldb/source/Target/Memory.cpp:65-66
+ // intersecting.
+ BlockMap::iterator previous = pos;
+ previous--;
+ AddrRange previous_range(previous->first,
----------------
This can just be:
```
BlockMap::iterator previous = pos - 1;
```
================
Comment at: lldb/source/Target/Memory.cpp:67-68
+ previous--;
+ AddrRange previous_range(previous->first,
+ previous->second->GetByteSize());
+ if (previous_range.DoesIntersect(flush_range))
----------------
name "chunk_range" like in the while loop below for consistency?
================
Comment at: lldb/source/Target/Process.cpp:488
m_profile_data_comm_mutex(), m_profile_data(), m_iohandler_sync(0),
- m_memory_cache(*this), m_allocated_memory_cache(*this),
- m_should_detach(false), m_next_event_action_up(), m_public_run_lock(),
- m_private_run_lock(), m_finalizing(false), m_finalize_called(false),
+ m_memory_cache(*this, GetMemoryCacheLineSize()),
+ m_allocated_memory_cache(*this), m_should_detach(false),
----------------
remove GetMemoryCacheLineSize() if we add virtual method to MemoryFromInferiorReader
================
Comment at: lldb/source/Target/Process.cpp:612
m_image_tokens.clear();
- m_memory_cache.Clear();
+ m_memory_cache.Clear(GetMemoryCacheLineSize());
m_allocated_memory_cache.Clear();
----------------
remove GetMemoryCacheLineSize() if we add virtual method to MemoryFromInferiorReader
================
Comment at: lldb/source/Target/Process.cpp:1456
m_mod_id.SetStopEventForLastNaturalStopID(event_sp);
- m_memory_cache.Clear();
+ m_memory_cache.Clear(GetMemoryCacheLineSize());
LLDB_LOGF(log, "Process::SetPrivateState (%s) stop_id = %u",
----------------
remove GetMemoryCacheLineSize() if we add virtual method to MemoryFromInferiorReader
================
Comment at: lldb/source/Target/Process.cpp:5575
m_thread_list.DiscardThreadPlans();
- m_memory_cache.Clear(true);
+ m_memory_cache.Clear(GetMemoryCacheLineSize(), true);
DoDidExec();
----------------
remove GetMemoryCacheLineSize() if we add virtual method to MemoryFromInferiorReader
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:32-69
+MemoryCacheTest::MemoryCacheTest()
+ : m_cache(*this, k_cache_line_size), m_inferior_read_count(0) {
+ for (size_t i = 0; i < k_memory_size; i++)
+ m_memory.push_back(static_cast<uint8_t>(i));
+}
+
+void MemoryCacheTest::AddRangeToL1Cache(lldb::addr_t addr, size_t len) {
----------------
Just inline these to avoid having to have a declaration inside the class and then these functions outside of the class?
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:34-35
+ : m_cache(*this, k_cache_line_size), m_inferior_read_count(0) {
+ for (size_t i = 0; i < k_memory_size; i++)
+ m_memory.push_back(static_cast<uint8_t>(i));
+}
----------------
Comment maybe saying something like:
```
// Fill memory from [0x0 - 0x256) with byte values that match the index. We will use this memory in each test and each test will start with a fresh copy.
```
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:75-76
+
+ m_cache.Read(10, result.data(), result.size(), error);
+ ASSERT_EQ(10, result[0]);
+
----------------
So we are reading 10 bytes, but only verifying the first byte in the 10 bytes we read? Why not verify all of them to be sure it worked with a for loop?
```
for (int i=0; i<result.size(); ++i)
ASSERT_EQ(i+10, result[i]);
```
or just do manual asserts:
```
ASSERT_EQ(10, result[0]);
ASSERT_EQ(11, result[1]);
ASSERT_EQ(12, result[2]);
...
```
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:81
+ m_cache.Read(10, result.data(), result.size(), error);
+ ASSERT_EQ(m_memory[10], result[0]);
+}
----------------
So with "IncrementAndFlushRange(10, 1);" we are modifying one byte at index 10 by incrementing it right? It isn't clear from the:
```
ASSERT_EQ(m_memory[10], result[0]);
```
What we are verifying here. Wouldn't it be simpler to do:
```
ASSERT_EQ(11, result[0]);
```
And also verify that all of the other 9 bytes we read were unchanged?
```
ASSERT_EQ(11, result[1]);
ASSERT_EQ(12, result[2]);
...
```
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:92
+ for (std::pair<lldb::addr_t, size_t> p : cached)
+ AddRangeToL1Cache(p.first, p.second);
+
----------------
seems weird to use AddRangeToL1Cache instead of just reading memory from these locations and it makes it less of a real world kind a test if we are mucking with the L1 cache directly. Makes the test a bit harder to follow. Maybe just reading from memory is easier to follow?:
```
// Read ranges from memory to populate the L1 cache
std::vector<uint8_t> result(10);
for (std::pair<lldb::addr_t, size_t> p : cached)
ReadByBytes(p.first, p.second);
```
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:98-100
+ size_t check_size = 50;
+ std::vector<uint8_t> result = ReadByBytes(0, check_size);
+ EXPECT_THAT(result, ::testing::ElementsAreArray(m_memory.data(), check_size));
----------------
I can't tell what these three lines are doing. Very hard to follow
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:121
+ for (std::pair<lldb::addr_t, size_t> p : cached)
+ AddRangeToL1Cache(p.first, p.second);
+
----------------
Same comment as last test about just reading from memory to populate the cache?
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:127-129
+ for (std::pair<lldb::addr_t, size_t> p : cached)
+ ReadByBytes(p.first, p.second);
+ EXPECT_EQ(0u, m_inferior_read_count);
----------------
How do we know this won't try and read any memory? Are we assured that IncrementAndFlushRange won't touch any ranges we are trying to read here?
================
Comment at: lldb/unittests/Target/MemoryCacheTest.cpp:132-134
+ size_t check_size = 50;
+ std::vector<uint8_t> result = ReadByBytes(0, check_size);
+ EXPECT_THAT(result, ::testing::ElementsAreArray(m_memory.data(), check_size));
----------------
What is this checking?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D77765/new/
https://reviews.llvm.org/D77765
More information about the lldb-commits
mailing list