Skip to content

Commit c2fe277

Browse files
WebAssembly: We should compile wasm functions in parallel
https://bugs.webkit.org/show_bug.cgi?id=165993 Reviewed by Keith Miller. This patch adds a very simple parallel compiler for Wasm code. This patch speeds up compiling the Unity headless benchmark by slightly more than 4x on my MBP. To make this safe, I perform all linking on the main thread. I also had to change some code inside Wasmb3IRGenerator to be thread safe. * b3/air/AirCustom.h: (JSC::B3::Air::WasmBoundsCheckCustom::generate): * b3/air/AirGenerationContext.h: * wasm/WasmB3IRGenerator.cpp: (JSC::Wasm::B3IRGenerator::B3IRGenerator): (JSC::Wasm::B3IRGenerator::emitExceptionCheck): (JSC::Wasm::createJSToWasmWrapper): (JSC::Wasm::parseAndCompile): * wasm/WasmB3IRGenerator.h: * wasm/WasmCallingConvention.h: (JSC::Wasm::CallingConvention::setupFrameInPrologue): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::parseAndValidateModule): (JSC::Wasm::Plan::run): * wasm/WasmPlan.h: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@210047 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent ba7aea2 commit c2fe277

File tree

8 files changed

+174
-46
lines changed

8 files changed

+174
-46
lines changed

Source/JavaScriptCore/ChangeLog

+29
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
2016-12-20 Saam Barati <[email protected]>
2+
3+
WebAssembly: We should compile wasm functions in parallel
4+
https://bugs.webkit.org/show_bug.cgi?id=165993
5+
6+
Reviewed by Keith Miller.
7+
8+
This patch adds a very simple parallel compiler for Wasm code.
9+
This patch speeds up compiling the Unity headless benchmark by
10+
slightly more than 4x on my MBP. To make this safe, I perform
11+
all linking on the main thread. I also had to change some code
12+
inside Wasmb3IRGenerator to be thread safe.
13+
14+
* b3/air/AirCustom.h:
15+
(JSC::B3::Air::WasmBoundsCheckCustom::generate):
16+
* b3/air/AirGenerationContext.h:
17+
* wasm/WasmB3IRGenerator.cpp:
18+
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
19+
(JSC::Wasm::B3IRGenerator::emitExceptionCheck):
20+
(JSC::Wasm::createJSToWasmWrapper):
21+
(JSC::Wasm::parseAndCompile):
22+
* wasm/WasmB3IRGenerator.h:
23+
* wasm/WasmCallingConvention.h:
24+
(JSC::Wasm::CallingConvention::setupFrameInPrologue):
25+
* wasm/WasmPlan.cpp:
26+
(JSC::Wasm::Plan::parseAndValidateModule):
27+
(JSC::Wasm::Plan::run):
28+
* wasm/WasmPlan.h:
29+
130
2016-12-20 Brent Fulgham <[email protected]>
231

332
Address some style problems found by static analysis

Source/JavaScriptCore/b3/air/AirCustom.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ struct WasmBoundsCheckCustom : public CommonCustomBase<WasmBoundsCheckCustom> {
313313
CCallHelpers::Jump outOfBounds = Inst(Air::Branch64, value, Arg::relCond(CCallHelpers::AboveOrEqual), inst.args[0], inst.args[1]).generate(jit, context);
314314

315315
context.latePaths.append(createSharedTask<GenerationContext::LatePathFunction>(
316-
[=] (CCallHelpers& jit, Air::GenerationContext&) {
316+
[outOfBounds, value] (CCallHelpers& jit, Air::GenerationContext& context) {
317317
outOfBounds.link(&jit);
318318
context.code->wasmBoundsCheckGenerator()->run(jit, value->pinnedGPR(), value->offset());
319319
}));

Source/JavaScriptCore/b3/air/AirGenerationContext.h

+5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ namespace JSC { namespace B3 { namespace Air {
3939
class Code;
4040

4141
struct GenerationContext {
42+
WTF_MAKE_NONCOPYABLE(GenerationContext);
43+
public:
44+
45+
GenerationContext() = default;
46+
4247
typedef void LatePathFunction(CCallHelpers&, GenerationContext&);
4348
typedef SharedTask<LatePathFunction> LatePath;
4449

Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

+23-21
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,6 @@ B3IRGenerator::B3IRGenerator(VM& vm, const ModuleInformation& info, Procedure& p
257257
ASSERT_UNUSED(pinnedGPR, m_memorySizeGPR == pinnedGPR);
258258
this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess);
259259
});
260-
261-
B3::PatchpointValue* foo = m_currentBlock->appendNew<B3::PatchpointValue>(m_proc, B3::Void, Origin());
262-
foo->setGenerator(
263-
[=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
264-
AllowMacroScratchRegisterUsage allowScratch(jit);
265-
});
266260
}
267261

268262
wasmCallingConvention().setupFrameInPrologue(&compilation->wasmCalleeMoveLocation, m_proc, Origin(), m_currentBlock);
@@ -277,7 +271,7 @@ void B3IRGenerator::emitExceptionCheck(CCallHelpers& jit, ExceptionType type)
277271
auto jumpToExceptionStub = jit.jump();
278272

279273
VM* vm = &m_vm;
280-
jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
274+
jit.addLinkTask([vm, jumpToExceptionStub] (LinkBuffer& linkBuffer) {
281275
linkBuffer.link(jumpToExceptionStub, CodeLocationLabel(vm->getCTIStub(throwExceptionFromWasmThunkGenerator).code()));
282276
});
283277
}
@@ -691,13 +685,14 @@ auto B3IRGenerator::addCall(uint32_t functionIndex, const Signature* signature,
691685
patchpoint->effects.writesPinned = true;
692686
patchpoint->effects.readsPinned = true;
693687

694-
patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
688+
Vector<UnlinkedWasmToWasmCall>* unlinkedWasmToWasmCalls = &m_unlinkedWasmToWasmCalls;
689+
patchpoint->setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
695690
AllowMacroScratchRegisterUsage allowScratch(jit);
696691

697692
CCallHelpers::Call call = jit.call();
698693

699-
jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
700-
m_unlinkedWasmToWasmCalls.append({ linkBuffer.locationOf(call), functionIndex });
694+
jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndex] (LinkBuffer& linkBuffer) {
695+
unlinkedWasmToWasmCalls->append({ linkBuffer.locationOf(call), functionIndex });
701696
});
702697
});
703698
});
@@ -819,7 +814,7 @@ void B3IRGenerator::dump(const Vector<ControlEntry>& controlStack, const Express
819814
dataLogLn("\n");
820815
}
821816

822-
static std::unique_ptr<B3::Compilation> createJSToWasmWrapper(VM& vm, WasmInternalFunction& function, const Signature* signature, MacroAssemblerCodePtr mainFunction, const MemoryInformation& memory)
817+
static void createJSToWasmWrapper(VM& vm, CompilationContext& compilationContext, WasmInternalFunction& function, const Signature* signature, const MemoryInformation& memory)
823818
{
824819
Procedure proc;
825820
BasicBlock* block = proc.addBlock();
@@ -876,13 +871,12 @@ static std::unique_ptr<B3::Compilation> createJSToWasmWrapper(VM& vm, WasmIntern
876871
patchpoint->append(ConstrainedValue(sizes[i], ValueRep::reg(memory.pinnedRegisters().sizeRegisters[i].sizeRegister)));
877872
}
878873

879-
patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
874+
CompilationContext* context = &compilationContext;
875+
patchpoint->setGenerator([context] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
880876
AllowMacroScratchRegisterUsage allowScratch(jit);
881877

882878
CCallHelpers::Call call = jit.call();
883-
jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
884-
linkBuffer.link(call, FunctionPtr(mainFunction.executableAddress()));
885-
});
879+
context->jsEntrypointToWasmEntrypointCall = call;
886880
});
887881
});
888882

@@ -904,15 +898,19 @@ static std::unique_ptr<B3::Compilation> createJSToWasmWrapper(VM& vm, WasmIntern
904898
RELEASE_ASSERT_NOT_REACHED();
905899
}
906900

907-
auto jsEntrypoint = std::make_unique<Compilation>(B3::compile(vm, proc));
901+
B3::prepareForGeneration(proc);
902+
B3::generate(proc, *compilationContext.jsEntrypointJIT);
903+
compilationContext.jsEntrypointByproducts = proc.releaseByproducts();
908904
function.jsToWasmEntrypoint.calleeSaveRegisters = proc.calleeSaveRegisters();
909-
return jsEntrypoint;
910905
}
911906

912-
Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(VM& vm, const uint8_t* functionStart, size_t functionLength, const Signature* signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& info, unsigned optLevel)
907+
Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(VM& vm, CompilationContext& compilationContext, const uint8_t* functionStart, size_t functionLength, const Signature* signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& info, unsigned optLevel)
913908
{
914909
auto result = std::make_unique<WasmInternalFunction>();
915910

911+
compilationContext.jsEntrypointJIT = std::make_unique<CCallHelpers>(&vm);
912+
compilationContext.wasmEntrypointJIT = std::make_unique<CCallHelpers>(&vm);
913+
916914
Procedure procedure;
917915
B3IRGenerator context(vm, info, procedure, result.get(), unlinkedWasmToWasmCalls, functionIndexSpace);
918916
FunctionParser<B3IRGenerator> parser(&vm, context, functionStart, functionLength, signature, functionIndexSpace, info);
@@ -927,10 +925,14 @@ Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(VM& vm,
927925
if (verbose)
928926
dataLog("Post SSA: ", procedure);
929927

930-
result->wasmEntrypoint.compilation = std::make_unique<B3::Compilation>(B3::compile(vm, procedure, optLevel));
931-
result->wasmEntrypoint.calleeSaveRegisters = procedure.calleeSaveRegisters();
928+
{
929+
B3::prepareForGeneration(procedure, optLevel);
930+
B3::generate(procedure, *compilationContext.wasmEntrypointJIT);
931+
compilationContext.wasmEntrypointByproducts = procedure.releaseByproducts();
932+
result->wasmEntrypoint.calleeSaveRegisters = procedure.calleeSaveRegisters();
933+
}
932934

933-
result->jsToWasmEntrypoint.compilation = createJSToWasmWrapper(vm, *result, signature, result->wasmEntrypoint.compilation->code(), info.memory);
935+
createJSToWasmWrapper(vm, compilationContext, *result, signature, info.memory);
934936
return WTFMove(result);
935937
}
936938

Source/JavaScriptCore/wasm/WasmB3IRGenerator.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#if ENABLE(WEBASSEMBLY)
2929

3030
#include "B3Compilation.h"
31+
#include "CCallHelpers.h"
3132
#include "VM.h"
3233
#include "WasmFormat.h"
3334
#include <wtf/Expected.h>
@@ -38,7 +39,15 @@ namespace JSC { namespace Wasm {
3839

3940
class MemoryInformation;
4041

41-
Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(VM&, const uint8_t*, size_t, const Signature*, Vector<UnlinkedWasmToWasmCall>&, const ImmutableFunctionIndexSpace&, const ModuleInformation&, unsigned optLevel = 1);
42+
struct CompilationContext {
43+
std::unique_ptr<CCallHelpers> jsEntrypointJIT;
44+
std::unique_ptr<B3::OpaqueByproducts> jsEntrypointByproducts;
45+
std::unique_ptr<CCallHelpers> wasmEntrypointJIT;
46+
std::unique_ptr<B3::OpaqueByproducts> wasmEntrypointByproducts;
47+
CCallHelpers::Call jsEntrypointToWasmEntrypointCall;
48+
};
49+
50+
Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(VM&, CompilationContext&, const uint8_t*, size_t, const Signature*, Vector<UnlinkedWasmToWasmCall>&, const ImmutableFunctionIndexSpace&, const ModuleInformation&, unsigned optLevel = 1);
4251

4352
} } // namespace JSC::Wasm
4453

Source/JavaScriptCore/wasm/WasmCallingConvention.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class CallingConvention {
9595
[=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
9696
GPRReg result = params[0].gpr();
9797
MacroAssembler::DataLabelPtr moveLocation = jit.moveWithPatch(MacroAssembler::TrustedImmPtr(nullptr), result);
98-
jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
98+
jit.addLinkTask([calleeMoveLocation, moveLocation] (LinkBuffer& linkBuffer) {
9999
*calleeMoveLocation = linkBuffer.locationOf(moveLocation);
100100
});
101101
});

Source/JavaScriptCore/wasm/WasmPlan.cpp

+100-22
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
#include "WasmModuleParser.h"
4040
#include "WasmValidate.h"
4141
#include <wtf/DataLog.h>
42+
#include <wtf/Locker.h>
43+
#include <wtf/MonotonicTime.h>
44+
#include <wtf/NumberOfCores.h>
4245
#include <wtf/StdLibExtras.h>
4346
#include <wtf/text/StringBuilder.h>
4447

@@ -60,6 +63,10 @@ Plan::Plan(VM* vm, const uint8_t* source, size_t sourceLength)
6063

6164
bool Plan::parseAndValidateModule()
6265
{
66+
MonotonicTime startTime;
67+
if (verbose || Options::reportCompileTimes())
68+
startTime = MonotonicTime::now();
69+
6370
{
6471
ModuleParser moduleParser(m_vm, m_source, m_sourceLength);
6572
auto parseResult = moduleParser.parse();
@@ -78,7 +85,7 @@ bool Plan::parseAndValidateModule()
7885
dataLogLn("Processing function starting at: ", m_functionLocationInBinary[functionIndex].start, " and ending at: ", m_functionLocationInBinary[functionIndex].end);
7986
const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start;
8087
size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
81-
ASSERT(Checked<uintptr_t>(bitwise_cast<uintptr_t>(functionStart)) + functionLength <= Checked<uintptr_t>(bitwise_cast<uintptr_t>(m_source)) + m_sourceLength);
88+
ASSERT(functionLength <= m_sourceLength);
8289
SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
8390
const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
8491

@@ -94,9 +101,15 @@ bool Plan::parseAndValidateModule()
94101
}
95102
}
96103

104+
if (verbose || Options::reportCompileTimes())
105+
dataLogLn("Took ", (MonotonicTime::now() - startTime).microseconds(), " us to validate module");
97106
return true;
98107
}
99108

109+
// We are creating a bunch of threads that touch the main thread's stack. This will make ASAN unhappy.
110+
// The reason this is OK is that we guarantee that the main thread doesn't continue until all threads
111+
// that could touch its stack are done executing.
112+
SUPPRESS_ASAN
100113
void Plan::run()
101114
{
102115
if (!parseAndValidateModule())
@@ -114,12 +127,16 @@ void Plan::run()
114127
return true;
115128
};
116129

117-
Vector<Vector<UnlinkedWasmToWasmCall>> unlinkedWasmToWasmCalls;
118130
if (!tryReserveCapacity(m_wasmToJSStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to JavaScript stubs")
119-
|| !tryReserveCapacity(unlinkedWasmToWasmCalls, m_functionLocationInBinary.size(), " unlinked WebAssembly to WebAssembly calls")
120-
|| !tryReserveCapacity(m_wasmInternalFunctions, m_functionLocationInBinary.size(), " WebAssembly functions"))
131+
|| !tryReserveCapacity(m_unlinkedWasmToWasmCalls, m_functionLocationInBinary.size(), " unlinked WebAssembly to WebAssembly calls")
132+
|| !tryReserveCapacity(m_wasmInternalFunctions, m_functionLocationInBinary.size(), " WebAssembly functions")
133+
|| !tryReserveCapacity(m_compilationContexts, m_functionLocationInBinary.size(), " compilation contexts"))
121134
return;
122135

136+
m_unlinkedWasmToWasmCalls.resize(m_functionLocationInBinary.size());
137+
m_wasmInternalFunctions.resize(m_functionLocationInBinary.size());
138+
m_compilationContexts.resize(m_functionLocationInBinary.size());
139+
123140
for (unsigned importIndex = 0; importIndex < m_moduleInformation->imports.size(); ++importIndex) {
124141
Import* import = &m_moduleInformation->imports[importIndex];
125142
if (import->kind != ExternalKind::Function)
@@ -132,31 +149,92 @@ void Plan::run()
132149
m_functionIndexSpace.buffer.get()[importFunctionIndex].code = m_wasmToJSStubs[importFunctionIndex].code().executableAddress();
133150
}
134151

135-
for (unsigned functionIndex = 0; functionIndex < m_functionLocationInBinary.size(); ++functionIndex) {
136-
if (verbose)
137-
dataLogLn("Processing function starting at: ", m_functionLocationInBinary[functionIndex].start, " and ending at: ", m_functionLocationInBinary[functionIndex].end);
138-
const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start;
139-
size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
140-
ASSERT(functionLength <= m_sourceLength);
141-
SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
142-
const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
143-
unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex;
144-
ASSERT(m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex == signatureIndex);
152+
m_currentIndex = 0;
153+
154+
auto doWork = [this] {
155+
while (true) {
156+
uint32_t functionIndex;
157+
{
158+
auto locker = holdLock(m_lock);
159+
if (m_currentIndex >= m_functionLocationInBinary.size())
160+
return;
161+
functionIndex = m_currentIndex;
162+
++m_currentIndex;
163+
}
164+
165+
const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start;
166+
size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
167+
ASSERT(functionLength <= m_sourceLength);
168+
SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
169+
const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
170+
unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex;
171+
ASSERT_UNUSED(functionIndexSpace, m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex == signatureIndex);
172+
ASSERT(validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation));
145173

146-
ASSERT(validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation));
174+
m_unlinkedWasmToWasmCalls[functionIndex] = Vector<UnlinkedWasmToWasmCall>();
175+
auto parseAndCompileResult = parseAndCompile(*m_vm, m_compilationContexts[functionIndex], functionStart, functionLength, signature, m_unlinkedWasmToWasmCalls[functionIndex], m_functionIndexSpace, *m_moduleInformation);
147176

148-
unlinkedWasmToWasmCalls.uncheckedAppend(Vector<UnlinkedWasmToWasmCall>());
149-
auto parseAndCompileResult = parseAndCompile(*m_vm, functionStart, functionLength, signature, unlinkedWasmToWasmCalls.at(functionIndex), m_functionIndexSpace, *m_moduleInformation);
150-
if (UNLIKELY(!parseAndCompileResult)) {
151-
m_errorMessage = parseAndCompileResult.error();
152-
return; // FIXME make this an Expected.
177+
if (UNLIKELY(!parseAndCompileResult)) {
178+
auto locker = holdLock(m_lock);
179+
if (!m_errorMessage) {
180+
// Multiple compiles could fail simultaneously. We arbitrarily choose the first.
181+
m_errorMessage = parseAndCompileResult.error(); // FIXME make this an Expected.
182+
}
183+
m_currentIndex = m_functionLocationInBinary.size();
184+
185+
// We will terminate on the next execution.
186+
continue;
187+
}
188+
189+
m_wasmInternalFunctions[functionIndex] = WTFMove(*parseAndCompileResult);
190+
}
191+
};
192+
193+
MonotonicTime startTime;
194+
if (verbose || Options::reportCompileTimes())
195+
startTime = MonotonicTime::now();
196+
197+
uint32_t threadCount = WTF::numberOfProcessorCores();
198+
uint32_t numWorkerThreads = threadCount - 1;
199+
Vector<ThreadIdentifier> threads;
200+
threads.reserveCapacity(numWorkerThreads);
201+
for (uint32_t i = 0; i < numWorkerThreads; i++)
202+
threads.uncheckedAppend(createThread("jsc.wasm-b3-compilation.thread", doWork));
203+
204+
doWork(); // Let the main thread do some work too.
205+
206+
for (uint32_t i = 0; i < numWorkerThreads; i++)
207+
waitForThreadCompletion(threads[i]);
208+
209+
for (uint32_t functionIndex = 0; functionIndex < m_functionLocationInBinary.size(); functionIndex++) {
210+
{
211+
CompilationContext& context = m_compilationContexts[functionIndex];
212+
{
213+
LinkBuffer linkBuffer(*m_vm, *context.wasmEntrypointJIT, nullptr);
214+
m_wasmInternalFunctions[functionIndex]->wasmEntrypoint.compilation =
215+
std::make_unique<B3::Compilation>(FINALIZE_CODE(linkBuffer, ("Wasm function")), WTFMove(context.wasmEntrypointByproducts));
216+
}
217+
218+
{
219+
LinkBuffer linkBuffer(*m_vm, *context.jsEntrypointJIT, nullptr);
220+
linkBuffer.link(context.jsEntrypointToWasmEntrypointCall, FunctionPtr(m_wasmInternalFunctions[functionIndex]->wasmEntrypoint.compilation->code().executableAddress()));
221+
222+
m_wasmInternalFunctions[functionIndex]->jsToWasmEntrypoint.compilation =
223+
std::make_unique<B3::Compilation>(FINALIZE_CODE(linkBuffer, ("Wasm JS entrypoint")), WTFMove(context.jsEntrypointByproducts));
224+
}
153225
}
154-
m_wasmInternalFunctions.uncheckedAppend(WTFMove(*parseAndCompileResult));
226+
227+
unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex;
155228
m_functionIndexSpace.buffer.get()[functionIndexSpace].code = m_wasmInternalFunctions[functionIndex]->wasmEntrypoint.compilation->code().executableAddress();
156229
}
157230

231+
if (verbose || Options::reportCompileTimes()) {
232+
dataLogLn("Took ", (MonotonicTime::now() - startTime).microseconds(),
233+
" us to compile and link the module");
234+
}
235+
158236
// Patch the call sites for each WebAssembly function.
159-
for (auto& unlinked : unlinkedWasmToWasmCalls) {
237+
for (auto& unlinked : m_unlinkedWasmToWasmCalls) {
160238
for (auto& call : unlinked)
161239
MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(m_functionIndexSpace.buffer.get()[call.functionIndex].code));
162240
}

0 commit comments

Comments
 (0)