зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1213437 - Less data copying when handling structured clones in MessageManager, r=baku
--HG-- extra : rebase_source : e38286f4fec560621d9eb49a40cc79eb6ce09b0a
This commit is contained in:
Родитель
dbc6bd7a9c
Коммит
bf7fdb8e75
|
@ -27,21 +27,19 @@ namespace ipc {
|
|||
bool
|
||||
StructuredCloneData::Copy(const StructuredCloneData& aData)
|
||||
{
|
||||
if (!aData.mData) {
|
||||
if (!aData.Data()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t* data = static_cast<uint64_t*>(js_malloc(aData.mDataLength));
|
||||
if (!data) {
|
||||
return false;
|
||||
if (aData.SharedData()) {
|
||||
mSharedData = aData.SharedData();
|
||||
} else {
|
||||
mSharedData =
|
||||
SharedJSAllocatedData::CreateFromExternalData(aData.Data(),
|
||||
aData.DataLength());
|
||||
NS_ENSURE_TRUE(mSharedData, false);
|
||||
}
|
||||
|
||||
memcpy(data, aData.mData, aData.mDataLength);
|
||||
|
||||
mData = data;
|
||||
mDataLength = aData.mDataLength;
|
||||
mDataOwned = eJSAllocated;
|
||||
|
||||
MOZ_ASSERT(BlobImpls().IsEmpty());
|
||||
BlobImpls().AppendElements(aData.BlobImpls());
|
||||
|
||||
|
@ -55,12 +53,12 @@ StructuredCloneData::Read(JSContext* aCx,
|
|||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult &aRv)
|
||||
{
|
||||
MOZ_ASSERT(mData);
|
||||
MOZ_ASSERT(Data());
|
||||
|
||||
nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
MOZ_ASSERT(global);
|
||||
|
||||
ReadFromBuffer(global, aCx, mData, mDataLength, aValue, aRv);
|
||||
ReadFromBuffer(global, aCx, Data(), DataLength(), aValue, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -68,26 +66,28 @@ StructuredCloneData::Write(JSContext* aCx,
|
|||
JS::Handle<JS::Value> aValue,
|
||||
ErrorResult &aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mData);
|
||||
MOZ_ASSERT(!Data());
|
||||
|
||||
StructuredCloneHolder::Write(aCx, aValue, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBuffer->steal(&mData, &mDataLength);
|
||||
uint64_t* data = nullptr;
|
||||
size_t dataLength = 0;
|
||||
mBuffer->steal(&data, &dataLength);
|
||||
mBuffer = nullptr;
|
||||
mDataOwned = eJSAllocated;
|
||||
mSharedData = new SharedJSAllocatedData(data, dataLength);
|
||||
}
|
||||
|
||||
void
|
||||
StructuredCloneData::WriteIPCParams(Message* aMsg) const
|
||||
{
|
||||
WriteParam(aMsg, mDataLength);
|
||||
WriteParam(aMsg, DataLength());
|
||||
|
||||
if (mDataLength) {
|
||||
if (DataLength()) {
|
||||
// Structured clone data must be 64-bit aligned.
|
||||
aMsg->WriteBytes(mData, mDataLength, sizeof(uint64_t));
|
||||
aMsg->WriteBytes(Data(), DataLength(), sizeof(uint64_t));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,31 +95,29 @@ bool
|
|||
StructuredCloneData::ReadIPCParams(const IPC::Message* aMsg,
|
||||
void** aIter)
|
||||
{
|
||||
MOZ_ASSERT(!mData);
|
||||
MOZ_ASSERT(!Data());
|
||||
|
||||
if (!ReadParam(aMsg, aIter, &mDataLength)) {
|
||||
size_t dataLength = 0;
|
||||
if (!ReadParam(aMsg, aIter, &dataLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mDataLength) {
|
||||
if (!dataLength) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t* dataBuffer = nullptr;
|
||||
const char** buffer =
|
||||
const_cast<const char**>(reinterpret_cast<char**>(&mData));
|
||||
const_cast<const char**>(reinterpret_cast<char**>(&dataBuffer));
|
||||
// Structured clone data must be 64-bit aligned.
|
||||
if (!aMsg->ReadBytes(aIter, buffer, mDataLength, sizeof(uint64_t))) {
|
||||
if (!aMsg->ReadBytes(aIter, buffer, dataLength, sizeof(uint64_t))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t* data = static_cast<uint64_t*>(js_malloc(mDataLength));
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
mSharedData = SharedJSAllocatedData::CreateFromExternalData(dataBuffer,
|
||||
dataLength);
|
||||
NS_ENSURE_TRUE(mSharedData, false);
|
||||
|
||||
memcpy(data, mData, mDataLength);
|
||||
mData = data;
|
||||
mDataOwned = eJSAllocated;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -127,17 +125,10 @@ bool
|
|||
StructuredCloneData::CopyExternalData(const void* aData,
|
||||
size_t aDataLength)
|
||||
{
|
||||
MOZ_ASSERT(!mData);
|
||||
uint64_t* data = static_cast<uint64_t*>(js_malloc(aDataLength));
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(data, aData, aDataLength);
|
||||
mData = data;
|
||||
mDataLength = aDataLength;
|
||||
mDataOwned = eJSAllocated;
|
||||
|
||||
MOZ_ASSERT(!Data());
|
||||
mSharedData = SharedJSAllocatedData::CreateFromExternalData(aData,
|
||||
aDataLength);
|
||||
NS_ENSURE_TRUE(mSharedData, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
#ifndef mozilla_dom_ipc_StructuredCloneData_h
|
||||
#define mozilla_dom_ipc_StructuredCloneData_h
|
||||
|
||||
#include <algorithm>
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/StructuredCloneHolder.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
|
@ -17,6 +20,51 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace ipc {
|
||||
|
||||
class SharedJSAllocatedData final
|
||||
{
|
||||
public:
|
||||
SharedJSAllocatedData(uint64_t* aData, size_t aDataLength)
|
||||
: mData(aData), mDataLength(aDataLength)
|
||||
{
|
||||
MOZ_ASSERT(mData);
|
||||
}
|
||||
|
||||
static already_AddRefed<SharedJSAllocatedData>
|
||||
CreateFromExternalData(const void* aData, size_t aDataLength)
|
||||
{
|
||||
uint64_t* data = Allocate64bitSafely(aDataLength);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memcpy(data, aData, aDataLength);
|
||||
nsRefPtr<SharedJSAllocatedData> sharedData =
|
||||
new SharedJSAllocatedData(data, aDataLength);
|
||||
return sharedData.forget();
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(SharedJSAllocatedData)
|
||||
|
||||
uint64_t* Data() const { return mData; }
|
||||
size_t DataLength() const { return mDataLength; }
|
||||
|
||||
private:
|
||||
~SharedJSAllocatedData()
|
||||
{
|
||||
js_free(mData);
|
||||
}
|
||||
|
||||
static uint64_t*
|
||||
Allocate64bitSafely(size_t aSize)
|
||||
{
|
||||
// Structured cloning requires 64-bit aligment.
|
||||
return static_cast<uint64_t*>(js_malloc(std::max(sizeof(uint64_t), aSize)));
|
||||
}
|
||||
|
||||
uint64_t* mData;
|
||||
size_t mDataLength;
|
||||
};
|
||||
|
||||
class StructuredCloneData : public StructuredCloneHolder
|
||||
{
|
||||
public:
|
||||
|
@ -24,18 +72,15 @@ public:
|
|||
: StructuredCloneHolder(StructuredCloneHolder::CloningSupported,
|
||||
StructuredCloneHolder::TransferringNotSupported,
|
||||
StructuredCloneHolder::DifferentProcess)
|
||||
, mData(nullptr)
|
||||
, mDataLength(0)
|
||||
, mDataOwned(eNone)
|
||||
, mExternalData(nullptr)
|
||||
, mExternalDataLength(0)
|
||||
{}
|
||||
|
||||
StructuredCloneData(const StructuredCloneData&) = delete;
|
||||
|
||||
~StructuredCloneData()
|
||||
{
|
||||
if (mDataOwned == eJSAllocated) {
|
||||
js_free(mData);
|
||||
}
|
||||
MOZ_ASSERT(!(mExternalData && mSharedData));
|
||||
}
|
||||
|
||||
StructuredCloneData&
|
||||
|
@ -63,22 +108,26 @@ public:
|
|||
|
||||
void UseExternalData(uint64_t* aData, size_t aDataLength)
|
||||
{
|
||||
MOZ_ASSERT(!mData);
|
||||
mData = aData;
|
||||
mDataLength = aDataLength;
|
||||
MOZ_ASSERT(mDataOwned == eNone);
|
||||
MOZ_ASSERT(!Data());
|
||||
mExternalData = aData;
|
||||
mExternalDataLength = aDataLength;
|
||||
}
|
||||
|
||||
bool CopyExternalData(const void* aData, size_t aDataLength);
|
||||
|
||||
uint64_t* Data() const
|
||||
{
|
||||
return mData;
|
||||
return mSharedData ? mSharedData->Data() : mExternalData;
|
||||
}
|
||||
|
||||
size_t DataLength() const
|
||||
{
|
||||
return mDataLength;
|
||||
return mSharedData ? mSharedData->DataLength() : mExternalDataLength;
|
||||
}
|
||||
|
||||
SharedJSAllocatedData* SharedData() const
|
||||
{
|
||||
return mSharedData;
|
||||
}
|
||||
|
||||
// For IPC serialization
|
||||
|
@ -86,12 +135,10 @@ public:
|
|||
bool ReadIPCParams(const IPC::Message* aMessage, void** aIter);
|
||||
|
||||
private:
|
||||
uint64_t* mData;
|
||||
size_t mDataLength;
|
||||
enum {
|
||||
eNone,
|
||||
eJSAllocated,
|
||||
} mDataOwned;
|
||||
uint64_t* MOZ_NON_OWNING_REF mExternalData;
|
||||
size_t mExternalDataLength;
|
||||
|
||||
RefPtr<SharedJSAllocatedData> mSharedData;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
|
|
Загрузка…
Ссылка в новой задаче