1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/ipc/SerializedStructuredCloneBuffer.h"
8 #include "js/StructuredClone.h"
12 void ParamTraits
<JSStructuredCloneData
>::Write(MessageWriter
* aWriter
,
13 const paramType
& aParam
) {
14 MOZ_ASSERT(!(aParam
.Size() % sizeof(uint64_t)));
16 // We can only construct shared memory regions up to 4Gb in size, making that
17 // the maximum possible JSStructuredCloneData size.
18 mozilla::CheckedUint32 size
= aParam
.Size();
19 if (!size
.isValid()) {
20 aWriter
->FatalError("JSStructuredCloneData over 4Gb in size");
23 WriteParam(aWriter
, size
.value());
25 MessageBufferWriter
bufWriter(aWriter
, size
.value());
26 aParam
.ForEachDataChunk([&](const char* aData
, size_t aSize
) {
27 return bufWriter
.WriteBytes(aData
, aSize
);
31 bool ParamTraits
<JSStructuredCloneData
>::Read(MessageReader
* aReader
,
34 if (!ReadParam(aReader
, &length
)) {
35 aReader
->FatalError("JSStructuredCloneData length read failed");
38 MOZ_ASSERT(!(length
% sizeof(uint64_t)));
40 // Borrowing is not suitable to use for IPC to hand out data because we often
41 // want to store the data somewhere for processing after IPC has released the
42 // underlying buffers.
44 // This deserializer previously used a mechanism to transfer ownership over
45 // the underlying buffers from IPC into the JSStructuredCloneData. This was
46 // removed when support for serializing over shared memory was added, as the
47 // benefit for avoiding copies was limited due to it only functioning for
48 // buffers under 64k in size (as larger buffers would be serialized using
49 // shared memory), and it added substantial complexity to the BufferList type
50 // and the IPC serialization layer due to things like buffer alignment. This
51 // can be revisited in the future if it turns out to be a noticable
52 // performance regression. (bug 1783242)
54 mozilla::BufferList
<js::SystemAllocPolicy
> buffers(0, 0, 4096);
55 MessageBufferReader
bufReader(aReader
, length
);
57 while (read
< length
) {
59 char* buf
= buffers
.AllocateBytes(length
- read
, &bufLen
);
61 // Would be nice to allow actor to control behaviour here (bug 1784307)
62 NS_ABORT_OOM(length
- read
);
65 if (!bufReader
.ReadBytesInto(buf
, bufLen
)) {
66 aReader
->FatalError("JSStructuredCloneData ReadBytesInto failed");
72 MOZ_ASSERT(read
== length
);
73 *aResult
= JSStructuredCloneData(
74 std::move(buffers
), JS::StructuredCloneScope::DifferentProcess
,
75 OwnTransferablePolicy::IgnoreTransferablesIfAny
);