Skip to content

[core][jsi] Zero-copy NativeArrayBuffer for native-backed data#46448

Merged
barthap merged 3 commits into
mainfrom
@barthap/e-m-c/arraybuffer-nativebuffer
Jun 4, 2026
Merged

[core][jsi] Zero-copy NativeArrayBuffer for native-backed data#46448
barthap merged 3 commits into
mainfrom
@barthap/e-m-c/arraybuffer-nativebuffer

Conversation

@barthap
Copy link
Copy Markdown
Contributor

@barthap barthap commented Jun 1, 2026

Why

Native-backed ArrayBuffers were copied when passed back to native functions expecting NativeArrayBuffer. React Native 0.86 now added an API to expose the original mutable backing buffer (see facebook/react-native#56156). This avoids unnecessary copies while preserving the existing copy behavior for JS-allocated buffers.

How

  • Use tryGetMutableBuffer()/tryBorrowMutableBuffer() to borrow native-backed ArrayBuffer memory and retain the underlying MutableBuffer for the lifetime of the native wrapper.
  • Keep the copy fallback for JS-allocated buffers, add typed-array view support with byteOffset
  • Moved hermes.h import to .cpp file to avoid unnecessarily including it in Swift interop

Test Plan

Added tests to verify native-backed sharing and copy fallback behavior:

  • iOS Unit tests
  • Android instrumented tests

Checklist

@expo-bot expo-bot added the contributor: internal PR author is a member, owner, or collaborator of the expo org label Jun 1, 2026
@barthap barthap changed the title [core] Zero-copy NativeArrayBuffer for native-backed data [core][jsi] Zero-copy NativeArrayBuffer for native-backed data Jun 1, 2026
@barthap barthap force-pushed the @barthap/e-m-c/arraybuffer-nativebuffer branch from 850a7df to 00681f5 Compare June 1, 2026 09:13
@expo-bot
Copy link
Copy Markdown
Collaborator

expo-bot commented Jun 1, 2026

The Pull Request introduced fingerprint changes against the base commit: 4d40f2d

Fingerprint diff
[
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/@expo/log-box",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "96eb947558c668452910b38e19e8acd4e20e45f2"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/@expo/log-box",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "d6e686eaa34955d1afa8fe5da9c2b07516bcd39a"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoConfigPlugins",
        "expoConfigPlugins",
        "rncoreAutolinkingAndroid",
        "rncoreAutolinkingIos"
      ],
      "hash": "5064c0fd09c047836a6169b03f0b80db9db7e3b2"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoConfigPlugins",
        "expoConfigPlugins",
        "rncoreAutolinkingAndroid",
        "rncoreAutolinkingIos"
      ],
      "hash": "2b6bb3ebf5b4cdccd9c36d1f03696a1756ca44fb"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-launcher",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "c82b5613bfcbfc95144780b10454785b810331c3"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-launcher",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "81ca1f6ab42ee720cf236ee69ce64eb216d1b0d9"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-menu",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "fd6ead988a9fee469abf2959ccbe71769fd6edea"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-menu",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "cdaa843725c7c9dc594a3824554cbc536488153b"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-gl",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "0a97bfb56b26ec5169bbdb84ca43fbf09ea261e9"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-gl",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "2e891b6e04fdf18879dc2244d62282a18e757dc3"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoAutolinkingIos"
      ],
      "hash": "bfcbddee800922ae0b731bcb96c052deeb56eab2"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoAutolinkingIos"
      ],
      "hash": "1956f1cc06a8e1a29efb1492aea72907146b642e"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-jsi/apple",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "0e24945cd7bda46039f5bb22a1de48150bd10c13"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-jsi/apple",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "17d5d1fc0c138b72629895f35d9de65cf1347bcf"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "node_modules/@shopify/react-native-skia",
      "reasons": [
        "rncoreAutolinkingAndroid"
      ],
      "hash": "4504c1f47440ab77923c2231edf8b06899578cdc"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "node_modules/@shopify/react-native-skia",
      "reasons": [
        "rncoreAutolinkingAndroid"
      ],
      "hash": "3f9e1aacb7f75a36f2668ba943381096ba26eac4"
    }
  }
]

Generated by PR labeler 🤖

@expo-bot expo-bot added the bot: passed checks ExpoBot has nothing to complain about label Jun 1, 2026
@barthap barthap force-pushed the @barthap/e-m-c/arraybuffer-nativebuffer branch from 9a667e3 to 550f9c9 Compare June 1, 2026 10:13
@barthap barthap requested review from lukmccall and tsapeta June 1, 2026 13:53
@barthap barthap marked this pull request as ready for review June 1, 2026 13:53
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

Subscribed to pull request

File Patterns Mentions
packages/expo-modules-core/** @Kudo, @lukmccall, @tsapeta

Generated by CodeMention

Comment thread packages/expo-modules-core/android/src/main/cpp/NativeArrayBuffer.cpp Outdated
Comment thread packages/expo-modules-core/android/src/main/cpp/NativeArrayBuffer.cpp Outdated
Comment thread packages/expo-modules-core/android/src/main/cpp/NativeArrayBuffer.h Outdated
Comment thread packages/expo-modules-jsi/apple/Sources/ExpoModulesJSI-Cxx/include/JSIUtils.h Outdated
Comment thread packages/expo-modules-core/android/src/main/cpp/NativeArrayBuffer.cpp Outdated
@barthap barthap force-pushed the @barthap/e-m-c/arraybuffer-nativebuffer branch from 4731ba8 to 6840dba Compare June 3, 2026 04:57
@barthap barthap requested a review from tsapeta June 3, 2026 08:24
@barthap barthap merged commit 293514f into main Jun 4, 2026
25 checks passed
@barthap barthap deleted the @barthap/e-m-c/arraybuffer-nativebuffer branch June 4, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot: fingerprint changed bot: passed checks ExpoBot has nothing to complain about contributor: internal PR author is a member, owner, or collaborator of the expo org

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants