-
Notifications
You must be signed in to change notification settings - Fork 6k
Switch PlatformMessages to hold data in Mappings #25867
Changes from all commits
dc66ee3
46796d9
fe80b2a
9aaa52d
63da9c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,6 +125,54 @@ class NonOwnedMapping final : public Mapping { | |
FML_DISALLOW_COPY_AND_ASSIGN(NonOwnedMapping); | ||
}; | ||
|
||
/// A Mapping like NonOwnedMapping, but uses Free as its release proc. | ||
class MallocMapping final : public Mapping { | ||
public: | ||
MallocMapping(); | ||
|
||
/// Creates a MallocMapping for a region of memory (without copying it). | ||
/// The function will `abort()` if the malloc fails. | ||
/// @param data The starting address of the mapping. | ||
/// @param size The size of the mapping in bytes. | ||
MallocMapping(uint8_t* data, size_t size); | ||
|
||
MallocMapping(fml::MallocMapping&& mapping); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason for the preference for this to be allocatable on the stack instead of using unique_ptr to own MallocMappings? Either way, the allocation is going to be on the heap. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't think about it much beyond just trying to keep it as close as possible to std::vector to make migration easier. I guess this is slightly more efficient since you can read the size without the indirection. |
||
|
||
~MallocMapping() override; | ||
|
||
/// Copies the data from `begin` to `end`. | ||
/// It's templated since void* arithemetic isn't allowed and we want support | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I understand this reasoning. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, they could. I was trying to make the migration as easy as possible, just added what I made it easiest. The problem was that we use uint8_t everywhere but when you are creating mappings from strings they use int8_t. |
||
/// for `uint8_t` and `char`. | ||
template <typename T> | ||
static MallocMapping Copy(const T* begin, const T* end) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs some error handling to ensure we don't read OOB. Specifically, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A suggestion: A variant I have found super useful in other projects is the following:
Which is an effective way of saying copy There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, I can't assert on size since it doesn't exist here. The reason I chose this signature was just because it matched the code I was migrating from std::vector. In the end I think I moved everything to the Copy signature with length, we could probably delete this but since it was helpful before I thought it might be helpful in the future. |
||
FML_DCHECK(end > begin); | ||
size_t length = end - begin; | ||
return Copy(begin, length); | ||
} | ||
|
||
/// Copies a region of memory into a MallocMapping. | ||
/// The function will `abort()` if the malloc fails. | ||
/// @param begin The starting address of where we will copy. | ||
/// @param length The length of the region to copy in bytes. | ||
static MallocMapping Copy(const void* begin, size_t length); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Docset for the signature. Specifically mentioning the following:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: If this were There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, I used void* in order to support uint8_t and int8_t. Otherwise I'd have to use templates like above. |
||
|
||
// |Mapping| | ||
size_t GetSize() const override; | ||
|
||
// |Mapping| | ||
const uint8_t* GetMapping() const override; | ||
|
||
/// Removes ownership of the data buffer. | ||
/// After this is called; the mapping will point to nullptr. | ||
[[nodiscard]] uint8_t* Release(); | ||
|
||
private: | ||
uint8_t* data_; | ||
size_t size_; | ||
|
||
FML_DISALLOW_COPY_AND_ASSIGN(MallocMapping); | ||
}; | ||
|
||
class SymbolMapping final : public Mapping { | ||
public: | ||
SymbolMapping(fml::RefPtr<fml::NativeLibrary> native_library, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "flutter/fml/mapping.h" | ||
#include "flutter/testing/testing.h" | ||
|
||
namespace fml { | ||
|
||
TEST(MallocMapping, EmptyContructor) { | ||
MallocMapping mapping; | ||
ASSERT_EQ(nullptr, mapping.GetMapping()); | ||
ASSERT_EQ(0u, mapping.GetSize()); | ||
} | ||
|
||
TEST(MallocMapping, NotEmptyContructor) { | ||
size_t length = 10; | ||
MallocMapping mapping(reinterpret_cast<uint8_t*>(malloc(length)), length); | ||
ASSERT_NE(nullptr, mapping.GetMapping()); | ||
ASSERT_EQ(length, mapping.GetSize()); | ||
} | ||
|
||
TEST(MallocMapping, MoveConstructor) { | ||
size_t length = 10; | ||
MallocMapping mapping(reinterpret_cast<uint8_t*>(malloc(length)), length); | ||
MallocMapping moved = std::move(mapping); | ||
|
||
ASSERT_EQ(nullptr, mapping.GetMapping()); | ||
ASSERT_EQ(0u, mapping.GetSize()); | ||
ASSERT_NE(nullptr, moved.GetMapping()); | ||
ASSERT_EQ(length, moved.GetSize()); | ||
} | ||
|
||
TEST(MallocMapping, Copy) { | ||
size_t length = 10; | ||
MallocMapping mapping(reinterpret_cast<uint8_t*>(malloc(length)), length); | ||
memset(const_cast<uint8_t*>(mapping.GetMapping()), 0xac, mapping.GetSize()); | ||
MallocMapping copied = | ||
MallocMapping::Copy(mapping.GetMapping(), mapping.GetSize()); | ||
|
||
ASSERT_NE(mapping.GetMapping(), copied.GetMapping()); | ||
ASSERT_EQ(mapping.GetSize(), copied.GetSize()); | ||
ASSERT_EQ( | ||
0, memcmp(mapping.GetMapping(), copied.GetMapping(), mapping.GetSize())); | ||
} | ||
|
||
TEST(MallocMapping, Release) { | ||
size_t length = 10; | ||
MallocMapping mapping(reinterpret_cast<uint8_t*>(malloc(length)), length); | ||
free(const_cast<uint8_t*>(mapping.Release())); | ||
ASSERT_EQ(nullptr, mapping.GetMapping()); | ||
ASSERT_EQ(0u, mapping.GetSize()); | ||
} | ||
|
||
} // namespace fml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error handling for OOM cases on malloc failures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done