Files
palemoon27/js/src/asmjs/WasmSerialize.h
T
roytam1 39770f3213 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1274192 part 1 - make the MediaDecoderReaderWrapper as a proxy of WaitForData(); r=jwwang (9debdca9a9)
- Bug 1274192 part 2 - make MDSM and SeekTask to adopt new MediaDecoderReaderWrapper API; r=jwwang (156f924dc9)
- Bug 1276495: Don't reset audio promises for video only seek. r=jwwang,jya (c4632c7ff6)
- Bug 1276318, part 1 - Fix leading tabs in ipc/glue. r=billm (46bcc4ccb3)
- Bug 1035125 Part 6: Take Chromium commit 3181ba39ee787e1b40f4aea4be23f4f666ad0945 to add Windows 10 version to enumeration. r=aklotz (af62c8065f)
- Bug 1270752 - Fix lifetime of buffer passed to PR_SetEnv(). r=jduell (bfce06ebea)
- Bug 1275117 - Fix static strings leaks when mozlogging is on. r=jduell (8e9066c5d7)
- Bug 1273048 - Add MOZ_GCC_VERSION_AT_MOST macro. r=froydnj (cfb5acdbe6)
- Bug 1269968 - Remove unnecessary deduction on RefPtr.h. r=froydnj (30cf9bbf47)
- Bug 525063 - add attribute to mark member variables that should be skipped by clang plugin initialization checker. r=nfroyd (78aa863f88)
- Bug 1278391 - add move constructor to EnumeratedArray (r=njn) (5effe4e473)
- Bug 1268518: Update basic-integer tests for rotations + clean up; r=sunfish (46827b6211)
- Bug 1270370 - Part 1: Move SetIteratorObject to MapObject.h; r=jorendorff (01a27fbd50)
- Bug 1270370 - Part 2: Expose MapIterator and SetIterator through ESClassValues; r=jorendorff (3edb3c7551)
- Bug 1267551 (part 3) - Use MOZ_MUST_USE more in js/src/builtin/. r=jonco. (ea96d0fae0)
- Bug 1267551 (part 4) - Use MOZ_MUST_USE more in js/src/asmjs/. r=bbouvier. (3e622c736d)
- Bug 1268910: Refactor WebAssembly trap handling; r=luke (b59394a287)
- Bug 1268910: Trap on edge cases for integer div/mod; r=sunfish (3d85230cc8)
- Bug 1267551 (part 5) - Use MOZ_MUST_USE more in js/src/ctypes/. r=sfink. (e6580fb645)
- Bug 1267551 (part 6) - Remove dead GenerateBlockId declaration. r=jorendorff. (74afcc549e)
- Bug 1240072 - Add public JS APIs related to modules r=shu Bug 1267551 (part 7) - Use MOZ_MUST_USE more in js/src/frontend/. r=jorendorff. (5275c57768)
- Bug 1267551 (part 8) - Use MOZ_MUST_USE more in js/src/gc/. r=terrence. (2572cc1c58)
- Bug 1261063 - Part 1 - Remove public Telemetry functions that return raw histogram instances. r=chutten (3a68653c8f)
- Bug 1261063 - Part 2 - Expose C++ function to clear Telemetry histograms. r=chutten (1f42f6aa1e)
- Bug 1261063 - Part 3 - Make RasterImage use the public Telemetry API. r=tnikkel (0f564f3836)
- Bug 1261063 - Part 4 - Use a count histogram for WebRTC call counts. r=jesup (b6b7b649e0)
- Bug 1270073 - Point to Telemetry documentation in Telemetry.h. r=chutten (517279b284)
- Bug 1261052 - Move C++ histogram implementation code into a separate module. r=gfritzsche. (66bcb1e167)
- Bug 1145164 - Allow non-unitary increments to count histograms. r=gfritzsche (507e076e28)
- Bug 1173447 - Add test for incremental pre-barriers when storing things under roots, r=jonco (caf8bd16be)
- Bug 1267551 (part 10) - Use MOZ_MUST_USE in AutoVectorRooterBase. r=terrence. (2c5ed87a9f)
- This catches a missing check. (b2fcd30fc5)
- Bug 1267551 (part 11b) - Follow-up to fix Android bustage. r=me (f464ca7b98)
- Bug 1271854 - Part 1: Allow specifying multiple GC zeal levels; r=terrence (da3c3e1281)
- Bug 1271854 - Part 2: Allow specifying zeal modes by name as well; r=terrence (f63926e45b)
- Bug 1271854 - Part 3: Avoid saving the GC zeal string inside the JS shell; r=terrence (f09b262e55)
- Bug 1270062 - Unbust Windows full duplex. a=Tomcat (3c8b5887b6)
- Bug 1270062 - Update libcubeb. rs=jesup (71805cb0e0)
- Bug 1270004 - Update libcubeb. rs=jesup (2d90b9662f)
- Bug 1280280 - Update cubeb to 073c9f011114. r=kinetik (6bee6a7f21)
- Bug 1280280 - Update media/libcube/update.sh to add cubeb_jack.cpp, and sort the list of files. r=kinetik (430b7533c4)
- Bug 1272604 - Add a zeal mode to check the heap after a moving GC r=terrence (85c018d71f)
- Bug 1272604 - Fix bad implicit conversion constructor build error r=me (5c4e1dbc44)
- Bug 1272604 - Fix hazard analysis failure r=me (0591aa2dca)
- Bug 1232417 - Use a Variant to represent the CrossCompartmentWrapperMap key; r=jonco (512da0bab3)
- Bug 1269928 - Fold DirectProxyHandler into Wrapper, which is now its only (non-test) consumer. r=efaust (7c6bb6e898)
- Bug 1273639 - Add a nonunified spidermonkey build, r=terrence (d6fa13545c)
- Bug 1273639 - Fix nonunified spidermonkey builds, r=terrence (3e0544510d)
- Bug 1273180 - Trigger major GC if necessary after minor GC r=terrence (a9a9be8b17)
- Bug 1268992 - Assert that the heap is empty after a shutdown GC; r=jonco (fe3ac5bdd6)
- Bug 1273908 - Refactor GC to make it easier to add new kinds of GC thing r=terrence (51c92e1b05)
2024-10-09 21:36:44 +08:00

351 lines
9.9 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
*
* Copyright 2015 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef wasm_serialize_h
#define wasm_serialize_h
#include "jit/MacroAssembler.h"
namespace js {
namespace wasm {
// Factor out common serialization, cloning and about:memory size-computation
// functions for reuse when serializing wasm and asm.js modules.
static inline uint8_t*
WriteBytes(uint8_t* dst, const void* src, size_t nbytes)
{
memcpy(dst, src, nbytes);
return dst + nbytes;
}
static inline const uint8_t*
ReadBytes(const uint8_t* src, void* dst, size_t nbytes)
{
memcpy(dst, src, nbytes);
return src + nbytes;
}
template <class T>
static inline uint8_t*
WriteScalar(uint8_t* dst, T t)
{
memcpy(dst, &t, sizeof(t));
return dst + sizeof(t);
}
template <class T>
static inline const uint8_t*
ReadScalar(const uint8_t* src, T* dst)
{
memcpy(dst, src, sizeof(*dst));
return src + sizeof(*dst);
}
static inline size_t
SerializedNameSize(PropertyName* name)
{
size_t s = sizeof(uint32_t);
if (name)
s += name->length() * (name->hasLatin1Chars() ? sizeof(Latin1Char) : sizeof(char16_t));
return s;
}
static inline uint8_t*
SerializeName(uint8_t* cursor, PropertyName* name)
{
MOZ_ASSERT_IF(name, !name->empty());
if (name) {
static_assert(JSString::MAX_LENGTH <= INT32_MAX, "String length must fit in 31 bits");
uint32_t length = name->length();
uint32_t lengthAndEncoding = (length << 1) | uint32_t(name->hasLatin1Chars());
cursor = WriteScalar<uint32_t>(cursor, lengthAndEncoding);
JS::AutoCheckCannotGC nogc;
if (name->hasLatin1Chars())
cursor = WriteBytes(cursor, name->latin1Chars(nogc), length * sizeof(Latin1Char));
else
cursor = WriteBytes(cursor, name->twoByteChars(nogc), length * sizeof(char16_t));
} else {
cursor = WriteScalar<uint32_t>(cursor, 0);
}
return cursor;
}
template <typename CharT>
static inline const uint8_t*
DeserializeChars(ExclusiveContext* cx, const uint8_t* cursor, size_t length, PropertyName** name)
{
Vector<CharT> tmp(cx);
CharT* src;
if ((size_t(cursor) & (sizeof(CharT) - 1)) != 0) {
// Align 'src' for AtomizeChars.
if (!tmp.resize(length))
return nullptr;
memcpy(tmp.begin(), cursor, length * sizeof(CharT));
src = tmp.begin();
} else {
src = (CharT*)cursor;
}
JSAtom* atom = AtomizeChars(cx, src, length);
if (!atom)
return nullptr;
*name = atom->asPropertyName();
return cursor + length * sizeof(CharT);
}
static inline const uint8_t*
DeserializeName(ExclusiveContext* cx, const uint8_t* cursor, PropertyName** name)
{
uint32_t lengthAndEncoding;
cursor = ReadScalar<uint32_t>(cursor, &lengthAndEncoding);
uint32_t length = lengthAndEncoding >> 1;
if (length == 0) {
*name = nullptr;
return cursor;
}
bool latin1 = lengthAndEncoding & 0x1;
return latin1
? DeserializeChars<Latin1Char>(cx, cursor, length, name)
: DeserializeChars<char16_t>(cx, cursor, length, name);
}
template <class T, size_t N>
static inline size_t
SerializedVectorSize(const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
{
size_t size = sizeof(uint32_t);
for (size_t i = 0; i < vec.length(); i++)
size += vec[i].serializedSize();
return size;
}
template <class T, size_t N>
static inline uint8_t*
SerializeVector(uint8_t* cursor, const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
{
cursor = WriteScalar<uint32_t>(cursor, vec.length());
for (size_t i = 0; i < vec.length(); i++)
cursor = vec[i].serialize(cursor);
return cursor;
}
template <class T, size_t N>
static inline const uint8_t*
DeserializeVector(ExclusiveContext* cx, const uint8_t* cursor,
mozilla::Vector<T, N, SystemAllocPolicy>* vec)
{
uint32_t length;
cursor = ReadScalar<uint32_t>(cursor, &length);
if (!vec->resize(length))
return nullptr;
for (size_t i = 0; i < vec->length(); i++) {
if (!(cursor = (*vec)[i].deserialize(cx, cursor)))
return nullptr;
}
return cursor;
}
template <class T, size_t N>
static inline MOZ_MUST_USE bool
CloneVector(JSContext* cx, const mozilla::Vector<T, N, SystemAllocPolicy>& in,
mozilla::Vector<T, N, SystemAllocPolicy>* out)
{
if (!out->resize(in.length()))
return false;
for (size_t i = 0; i < in.length(); i++) {
if (!in[i].clone(cx, &(*out)[i]))
return false;
}
return true;
}
template <class T, size_t N>
static inline size_t
SizeOfVectorExcludingThis(const mozilla::Vector<T, N, SystemAllocPolicy>& vec,
MallocSizeOf mallocSizeOf)
{
size_t size = vec.sizeOfExcludingThis(mallocSizeOf);
for (const T& t : vec)
size += t.sizeOfExcludingThis(mallocSizeOf);
return size;
}
template <class T, size_t N>
static inline size_t
SerializedPodVectorSize(const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
{
return sizeof(uint32_t) +
vec.length() * sizeof(T);
}
template <class T, size_t N>
static inline uint8_t*
SerializePodVector(uint8_t* cursor, const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
{
cursor = WriteScalar<uint32_t>(cursor, vec.length());
cursor = WriteBytes(cursor, vec.begin(), vec.length() * sizeof(T));
return cursor;
}
template <class T, size_t N>
static inline const uint8_t*
DeserializePodVector(ExclusiveContext* cx, const uint8_t* cursor,
mozilla::Vector<T, N, SystemAllocPolicy>* vec)
{
uint32_t length;
cursor = ReadScalar<uint32_t>(cursor, &length);
if (!vec->resize(length))
return nullptr;
cursor = ReadBytes(cursor, vec->begin(), length * sizeof(T));
return cursor;
}
template <class T, size_t N>
static inline MOZ_MUST_USE bool
ClonePodVector(JSContext* cx, const mozilla::Vector<T, N, SystemAllocPolicy>& in,
mozilla::Vector<T, N, SystemAllocPolicy>* out)
{
if (!out->resize(in.length()))
return false;
mozilla::PodCopy(out->begin(), in.begin(), in.length());
return true;
}
static inline MOZ_MUST_USE bool
GetCPUID(uint32_t* cpuId)
{
enum Arch {
X86 = 0x1,
X64 = 0x2,
ARM = 0x3,
MIPS = 0x4,
MIPS64 = 0x5,
ARCH_BITS = 3
};
#if defined(JS_CODEGEN_X86)
MOZ_ASSERT(uint32_t(jit::CPUInfo::GetSSEVersion()) <= (UINT32_MAX >> ARCH_BITS));
*cpuId = X86 | (uint32_t(jit::CPUInfo::GetSSEVersion()) << ARCH_BITS);
return true;
#elif defined(JS_CODEGEN_X64)
MOZ_ASSERT(uint32_t(jit::CPUInfo::GetSSEVersion()) <= (UINT32_MAX >> ARCH_BITS));
*cpuId = X64 | (uint32_t(jit::CPUInfo::GetSSEVersion()) << ARCH_BITS);
return true;
#elif defined(JS_CODEGEN_ARM)
MOZ_ASSERT(jit::GetARMFlags() <= (UINT32_MAX >> ARCH_BITS));
*cpuId = ARM | (jit::GetARMFlags() << ARCH_BITS);
return true;
#elif defined(JS_CODEGEN_MIPS32)
MOZ_ASSERT(jit::GetMIPSFlags() <= (UINT32_MAX >> ARCH_BITS));
*cpuId = MIPS | (jit::GetMIPSFlags() << ARCH_BITS);
return true;
#elif defined(JS_CODEGEN_MIPS64)
MOZ_ASSERT(jit::GetMIPSFlags() <= (UINT32_MAX >> ARCH_BITS));
*cpuId = MIPS64 | (jit::GetMIPSFlags() << ARCH_BITS);
return true;
#else
return false;
#endif
}
class MachineId
{
uint32_t cpuId_;
JS::BuildIdCharVector buildId_;
public:
MOZ_MUST_USE bool extractCurrentState(ExclusiveContext* cx) {
if (!cx->buildIdOp())
return false;
if (!cx->buildIdOp()(&buildId_))
return false;
if (!GetCPUID(&cpuId_))
return false;
return true;
}
size_t serializedSize() const {
return sizeof(uint32_t) +
SerializedPodVectorSize(buildId_);
}
uint8_t* serialize(uint8_t* cursor) const {
cursor = WriteScalar<uint32_t>(cursor, cpuId_);
cursor = SerializePodVector(cursor, buildId_);
return cursor;
}
const uint8_t* deserialize(ExclusiveContext* cx, const uint8_t* cursor) {
(cursor = ReadScalar<uint32_t>(cursor, &cpuId_)) &&
(cursor = DeserializePodVector(cx, cursor, &buildId_));
return cursor;
}
bool operator==(const MachineId& rhs) const {
return cpuId_ == rhs.cpuId_ &&
buildId_.length() == rhs.buildId_.length() &&
mozilla::PodEqual(buildId_.begin(), rhs.buildId_.begin(), buildId_.length());
}
bool operator!=(const MachineId& rhs) const {
return !(*this == rhs);
}
};
struct ScopedCacheEntryOpenedForWrite
{
ExclusiveContext* cx;
const size_t serializedSize;
uint8_t* memory;
intptr_t handle;
ScopedCacheEntryOpenedForWrite(ExclusiveContext* cx, size_t serializedSize)
: cx(cx), serializedSize(serializedSize), memory(nullptr), handle(-1)
{}
~ScopedCacheEntryOpenedForWrite() {
if (memory)
cx->asmJSCacheOps().closeEntryForWrite(serializedSize, memory, handle);
}
};
struct ScopedCacheEntryOpenedForRead
{
ExclusiveContext* cx;
size_t serializedSize;
const uint8_t* memory;
intptr_t handle;
explicit ScopedCacheEntryOpenedForRead(ExclusiveContext* cx)
: cx(cx), serializedSize(0), memory(nullptr), handle(0)
{}
~ScopedCacheEntryOpenedForRead() {
if (memory)
cx->asmJSCacheOps().closeEntryForRead(serializedSize, memory, handle);
}
};
} // namespace wasm
} // namespace js
#endif // wasm_serialize_h