Bug 1556668 - Move Wasm's MapFile from SpiderMonkey to Gecko to eliminate an NSPR dependency. r=luke

Differential Revision: https://phabricator.services.mozilla.com/D33605

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2019-06-04 18:43:02 +00:00
parent 7a1acfce91
commit 184ec53bf9
7 changed files with 56 additions and 113 deletions

View File

@ -3017,6 +3017,39 @@ void BackgroundRequestChild::PreprocessHelper::RunOnOwningThread() {
}
}
class MemUnmap {
uint32_t mSize = 0;
public:
MemUnmap() = default;
explicit MemUnmap(uint32_t aSize) : mSize(aSize) {}
void operator()(uint8_t* aP) {
MOZ_ASSERT(mSize);
PR_MemUnmap(aP, mSize);
}
};
using UniqueMapping = UniquePtr<uint8_t, MemUnmap>;
static UniqueMapping MapFile(PRFileDesc* aFile, PRFileInfo* aInfo) {
if (PR_GetOpenFileInfo(aFile, aInfo) != PR_SUCCESS) {
return nullptr;
}
PRFileMap* map = PR_CreateFileMap(aFile, aInfo->size, PR_PROT_READONLY);
if (!map) {
return nullptr;
}
// PRFileMap objects do not need to be kept alive after the memory has been
// mapped, so unconditionally close the PRFileMap, regardless of whether
// PR_MemMap succeeds.
uint8_t* memory = (uint8_t*)PR_MemMap(map, 0, aInfo->size);
PR_CloseFileMap(map);
return UniqueMapping(memory, MemUnmap(aInfo->size));
}
void BackgroundRequestChild::PreprocessHelper::ProcessCurrentStream() {
MOZ_ASSERT(!IsOnOwningThread());
MOZ_ASSERT(!mStreams.IsEmpty());
@ -3038,8 +3071,16 @@ void BackgroundRequestChild::PreprocessHelper::ProcessCurrentStream() {
MOZ_ASSERT(mCurrentBytecodeFileDesc);
PRFileInfo bytecodeInfo;
UniqueMapping bytecodeMapping =
MapFile(mCurrentBytecodeFileDesc, &bytecodeInfo);
if (NS_WARN_IF(!bytecodeMapping)) {
ContinueWithStatus(NS_ERROR_FAILURE);
return;
}
RefPtr<JS::WasmModule> module =
JS::DeserializeWasmModule(mCurrentBytecodeFileDesc, nullptr, 0);
JS::DeserializeWasmModule(bytecodeMapping.get(), bytecodeInfo.size);
if (NS_WARN_IF(!module)) {
ContinueWithStatus(NS_ERROR_FAILURE);
return;

View File

@ -5819,8 +5819,8 @@ JS_PUBLIC_API RefPtr<JS::WasmModule> JS::GetWasmModule(HandleObject obj) {
}
JS_PUBLIC_API RefPtr<JS::WasmModule> JS::DeserializeWasmModule(
PRFileDesc* bytecode, UniqueChars filename, unsigned line) {
return wasm::DeserializeModule(bytecode, std::move(filename), line);
const uint8_t* bytecode, size_t bytecodeLength) {
return wasm::DeserializeModule(bytecode, bytecodeLength);
}
JS_PUBLIC_API void JS::SetProcessLargeAllocationFailureCallback(

View File

@ -3029,7 +3029,7 @@ extern JS_PUBLIC_API RefPtr<WasmModule> GetWasmModule(HandleObject obj);
*/
extern JS_PUBLIC_API RefPtr<WasmModule> DeserializeWasmModule(
PRFileDesc* bytecode, JS::UniqueChars filename, unsigned line);
const uint8_t* bytecode, size_t bytecodeLength);
/**
* If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS

View File

@ -14,29 +14,4 @@
# include <sys/time.h>
# include <time.h>
int32_t PR_FileDesc2NativeHandle(PRFileDesc* fd) {
MOZ_CRASH("PR_FileDesc2NativeHandle");
}
PRStatus PR_GetOpenFileInfo(PRFileDesc* fd, PRFileInfo* info) {
MOZ_CRASH("PR_GetOpenFileInfo");
}
int32_t PR_Seek(PRFileDesc* fd, int32_t offset, PRSeekWhence whence) {
MOZ_CRASH("PR_Seek");
}
PRFileMap* PR_CreateFileMap(PRFileDesc* fd, int64_t size,
PRFileMapProtect prot) {
MOZ_CRASH("PR_CreateFileMap");
}
void* PR_MemMap(PRFileMap* fmap, int64_t offset, uint32_t len) {
MOZ_CRASH("PR_MemMap");
}
PRStatus PR_MemUnmap(void* addr, uint32_t len) { MOZ_CRASH("PR_MemUnmap"); }
PRStatus PR_CloseFileMap(PRFileMap* fmap) { MOZ_CRASH("PR_CloseFileMap"); }
#endif /* JS_POSIX_NSPR */

View File

@ -11,42 +11,6 @@
# include "jspubtd.h"
int32_t PR_FileDesc2NativeHandle(PRFileDesc* fd);
enum PRFileType { PR_FILE_FILE = 1, PR_FILE_DIRECTORY = 2, PR_FILE_OTHER = 3 };
struct PRFileInfo {
PRFileType type;
int32_t size;
int64_t creationTime;
int64_t modifyTime;
};
typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
PRStatus PR_GetOpenFileInfo(PRFileDesc* fd, PRFileInfo* info);
enum PRSeekWhence { PR_SEEK_SET = 0, PR_SEEK_CUR = 1, PR_SEEK_END = 2 };
int32_t PR_Seek(PRFileDesc* fd, int32_t offset, PRSeekWhence whence);
enum PRFileMapProtect {
PR_PROT_READONLY,
PR_PROT_READWRITE,
PR_PROT_WRITECOPY
};
struct PRFileMap;
PRFileMap* PR_CreateFileMap(PRFileDesc* fd, int64_t size,
PRFileMapProtect prot);
void* PR_MemMap(PRFileMap* fmap, int64_t offset, uint32_t len);
PRStatus PR_MemUnmap(void* addr, uint32_t len);
PRStatus PR_CloseFileMap(PRFileMap* fmap);
#endif /* JS_POSIX_NSPR */
#endif /* vm_PosixNSPR_h */

View File

@ -357,39 +357,8 @@ bool wasm::GetOptimizedEncodingBuildId(JS::BuildIdCharVector* buildId) {
return true;
}
struct MemUnmap {
uint32_t size;
MemUnmap() : size(0) {}
explicit MemUnmap(uint32_t size) : size(size) {}
void operator()(uint8_t* p) {
MOZ_ASSERT(size);
PR_MemUnmap(p, size);
}
};
typedef UniquePtr<uint8_t, MemUnmap> UniqueMapping;
static UniqueMapping MapFile(PRFileDesc* file, PRFileInfo* info) {
if (PR_GetOpenFileInfo(file, info) != PR_SUCCESS) {
return nullptr;
}
PRFileMap* map = PR_CreateFileMap(file, info->size, PR_PROT_READONLY);
if (!map) {
return nullptr;
}
// PRFileMap objects do not need to be kept alive after the memory has been
// mapped, so unconditionally close the PRFileMap, regardless of whether
// PR_MemMap succeeds.
uint8_t* memory = (uint8_t*)PR_MemMap(map, 0, info->size);
PR_CloseFileMap(map);
return UniqueMapping(memory, MemUnmap(info->size));
}
RefPtr<JS::WasmModule> wasm::DeserializeModule(PRFileDesc* bytecodeFile,
UniqueChars filename,
unsigned line) {
RefPtr<JS::WasmModule> wasm::DeserializeModule(const uint8_t* bytecode,
size_t bytecodeLength) {
// We have to compile new code here so if we're fundamentally unable to
// compile, we have to fail. If you change this code, update the
// MutableCompileArgs setting below.
@ -397,23 +366,17 @@ RefPtr<JS::WasmModule> wasm::DeserializeModule(PRFileDesc* bytecodeFile,
return nullptr;
}
PRFileInfo bytecodeInfo;
UniqueMapping bytecodeMapping = MapFile(bytecodeFile, &bytecodeInfo);
if (!bytecodeMapping) {
MutableBytes bytecodeCopy = js_new<ShareableBytes>();
if (!bytecodeCopy ||
!bytecodeCopy->bytes.initLengthUninitialized(bytecodeLength)) {
return nullptr;
}
MutableBytes bytecode = js_new<ShareableBytes>();
if (!bytecode ||
!bytecode->bytes.initLengthUninitialized(bytecodeInfo.size)) {
return nullptr;
}
memcpy(bytecode->bytes.begin(), bytecodeMapping.get(), bytecodeInfo.size);
memcpy(bytecodeCopy->bytes.begin(), bytecode, bytecodeLength);
ScriptedCaller scriptedCaller;
scriptedCaller.filename = std::move(filename);
scriptedCaller.line = line;
scriptedCaller.filename = nullptr;
scriptedCaller.line = 0;
MutableCompileArgs args = js_new<CompileArgs>(std::move(scriptedCaller));
if (!args) {
@ -438,7 +401,7 @@ RefPtr<JS::WasmModule> wasm::DeserializeModule(PRFileDesc* bytecodeFile,
UniqueChars error;
UniqueCharsVector warnings;
SharedModule module = CompileBuffer(*args, *bytecode, &error, &warnings);
SharedModule module = CompileBuffer(*args, *bytecodeCopy, &error, &warnings);
if (!module) {
return nullptr;
}

View File

@ -225,8 +225,8 @@ typedef RefPtr<const Module> SharedModule;
MOZ_MUST_USE bool GetOptimizedEncodingBuildId(JS::BuildIdCharVector* buildId);
RefPtr<JS::WasmModule> DeserializeModule(PRFileDesc* bytecode,
UniqueChars filename, unsigned line);
RefPtr<JS::WasmModule> DeserializeModule(const uint8_t* bytecode,
size_t bytecodeLength);
} // namespace wasm
} // namespace js