Skip to content

Commit f338920

Browse files
Andrei Shikovfacebook-github-bot
authored andcommitted
Cleanup ReadableMapBuffer
Summary: Cleans up `ReadableMapBuffer` APIs and migrates to use `std::vector` instead of raw pointer array. Also uses `fbjni` utility to allocate the bytes instead of making manual JNI calls. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D33513027 fbshipit-source-id: afe7d320d12830503de4c9994117d849f0b25245
1 parent aaff15c commit f338920

File tree

4 files changed

+17
-63
lines changed

4 files changed

+17
-63
lines changed

ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class ReadableMapBuffer implements Iterable<ReadableMapBuffer.MapBufferEn
5555
@SuppressWarnings("unused")
5656
private short mCount = 0;
5757

58+
@DoNotStrip
5859
private ReadableMapBuffer(HybridData hybridData) {
5960
mHybridData = hybridData;
6061
}
@@ -64,23 +65,13 @@ private ReadableMapBuffer(ByteBuffer buffer) {
6465
readHeader();
6566
}
6667

67-
private native ByteBuffer importByteBufferAllocateDirect();
68-
6968
private native ByteBuffer importByteBuffer();
7069

7170
@SuppressWarnings("unused")
7271
@DoNotStrip
7372
@Nullable
7473
private HybridData mHybridData;
7574

76-
@Override
77-
protected void finalize() throws Throwable {
78-
super.finalize();
79-
if (mHybridData != null) {
80-
mHybridData.resetNative();
81-
}
82-
}
83-
8475
private int getKeyOffsetForBucketIndex(int bucketIndex) {
8576
return HEADER_SIZE + BUCKET_SIZE * bucketIndex;
8677
}

ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/react/common/mapbuffer/ReadableMapBuffer.cpp

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,10 @@ namespace react {
1313
void ReadableMapBuffer::registerNatives() {
1414
registerHybrid({
1515
makeNativeMethod("importByteBuffer", ReadableMapBuffer::importByteBuffer),
16-
makeNativeMethod(
17-
"importByteBufferAllocateDirect",
18-
ReadableMapBuffer::importByteBufferAllocateDirect),
1916
});
2017
}
2118

22-
jni::local_ref<jni::JByteBuffer>
23-
ReadableMapBuffer::importByteBufferAllocateDirect() {
24-
// TODO T83483191: Using this method is safer than "importByteBuffer" because
25-
// ByteBuffer memory will be deallocated once the "Java ByteBuffer" is
26-
// deallocated. Next steps:
27-
// - Validate perf of this method vs importByteBuffer
28-
// - Validate that there's no leaking of memory
29-
react_native_assert(
30-
(serializedData_ != nullptr && serializedDataSize_ != 0) &&
31-
"Error serializedData_ is not initialized");
32-
auto ret = jni::JByteBuffer::allocateDirect(serializedDataSize_);
33-
// TODO T83483191: avoid allocating serializedData_ when using
34-
// JByteBuffer::allocateDirect
35-
std::memcpy(
36-
ret->getDirectBytes(), (void *)serializedData_, serializedDataSize_);
37-
38-
// Deallocate serializedData_ since it's not necessary anymore
39-
delete[] serializedData_;
40-
serializedData_ = nullptr;
41-
serializedDataSize_ = 0;
42-
return ret;
43-
}
44-
45-
jni::JByteBuffer::javaobject ReadableMapBuffer::importByteBuffer() {
19+
jni::local_ref<jni::JByteBuffer> ReadableMapBuffer::importByteBuffer() {
4620
// TODO T83483191: Reevaluate what's the best approach here (allocateDirect vs
4721
// DirectByteBuffer).
4822
//
@@ -55,21 +29,19 @@ jni::JByteBuffer::javaobject ReadableMapBuffer::importByteBuffer() {
5529
// - Add flags to describe if the data was already 'imported'
5630
// - Long-term: Consider creating a big ByteBuffer that can be re-used to
5731
// transfer data of multitple Maps
58-
return static_cast<jni::JByteBuffer::javaobject>(
59-
jni::Environment::current()->NewDirectByteBuffer(
60-
(void *)serializedData_, serializedDataSize_));
32+
return jni::JByteBuffer::wrapBytes(
33+
serializedData_.data(), serializedData_.size());
6134
}
6235

6336
jni::local_ref<ReadableMapBuffer::jhybridobject>
6437
ReadableMapBuffer::createWithContents(MapBuffer &&map) {
6538
return newObjectCxxArgs(std::move(map));
6639
}
6740

68-
ReadableMapBuffer::~ReadableMapBuffer() {
69-
if (serializedData_ != nullptr) {
70-
delete[] serializedData_;
71-
serializedData_ = nullptr;
72-
}
41+
ReadableMapBuffer::ReadableMapBuffer(MapBuffer &&map)
42+
: serializedData_(std::move(map.bytes_)) {
43+
react_native_assert(
44+
(serializedData_.size() != 0) && "Error no content in map");
7345
}
7446

7547
} // namespace react

ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/react/common/mapbuffer/ReadableMapBuffer.h

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,15 @@ class ReadableMapBuffer : public jni::HybridClass<ReadableMapBuffer> {
2323

2424
static void registerNatives();
2525

26-
static jni::local_ref<jhybridobject> createWithContents(MapBuffer &&map);
26+
static jni::local_ref<ReadableMapBuffer::jhybridobject> createWithContents(
27+
MapBuffer &&map);
2728

28-
jni::local_ref<jni::JByteBuffer> importByteBufferAllocateDirect();
29+
explicit ReadableMapBuffer(MapBuffer &&map);
2930

30-
jni::JByteBuffer::javaobject importByteBuffer();
31-
32-
~ReadableMapBuffer();
31+
jni::local_ref<jni::JByteBuffer> importByteBuffer();
3332

3433
private:
35-
uint8_t *serializedData_ = nullptr;
36-
37-
int32_t serializedDataSize_ = 0;
38-
39-
friend HybridBase;
40-
41-
explicit ReadableMapBuffer(MapBuffer &&map) {
42-
serializedDataSize_ = map.getBufferSize();
43-
react_native_assert(
44-
(serializedDataSize_ != 0) && "Error no content in map");
45-
serializedData_ = new Byte[serializedDataSize_];
46-
map.copy(serializedData_);
47-
}
34+
std::vector<uint8_t> serializedData_;
4835
};
4936

5037
} // namespace react

ReactCommon/react/renderer/mapbuffer/MapBuffer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
namespace facebook {
1616
namespace react {
1717

18+
class ReadableMapBuffer;
19+
1820
/**
1921
* MapBuffer is an optimized map format for transferring data like props between
2022
* C++ and other platforms The implementation of this map is optimized to:
@@ -31,6 +33,8 @@ namespace react {
3133
* - have minimal APK size and build time impact.
3234
*/
3335
class MapBuffer {
36+
friend ReadableMapBuffer;
37+
3438
private:
3539
// Buffer and its size
3640
std::vector<uint8_t> const bytes_;

0 commit comments

Comments
 (0)