Diff
Modified: trunk/JSTests/stress/sampling-profiler/samplingProfiler.js (271185 => 271186)
--- trunk/JSTests/stress/sampling-profiler/samplingProfiler.js 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/JSTests/stress/sampling-profiler/samplingProfiler.js 2021-01-06 03:03:43 UTC (rev 271186)
@@ -43,11 +43,13 @@
stackTrace = [...stackTrace];
let node = tree;
+ let prev = null;
for (let i = stackTrace.length; i--; ) {
+ prev = node;
node = node.children[stackTrace[i]];
if (!node) {
if (verbose)
- print("failing on " + i + " : " + stackTrace[i]);
+ print("failing on " + i + " : " + stackTrace[i], " ", JSON.stringify(Object.getOwnPropertyNames(prev.children)));
return false;
}
}
Modified: trunk/JSTests/stress/sampling-profiler-wasm-name-section.js (271185 => 271186)
--- trunk/JSTests/stress/sampling-profiler-wasm-name-section.js 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/JSTests/stress/sampling-profiler-wasm-name-section.js 2021-01-06 03:03:43 UTC (rev 271186)
@@ -69,5 +69,5 @@
var wasmEntry = function() {
return instance.exports._parrot(1);
};
- runTest(wasmEntry, ["_silly", "(unknown)", "<?>.wasm-function[_eggs]", "<?>.wasm-function[_bacon]", "<?>.wasm-function[_spam]", "<?>.wasm-function[_parrot]", "wasm-stub", "24", "wasmEntry"]);
+ runTest(wasmEntry, ["_silly", "(unknown)", "<?>.wasm-function[_eggs]", "<?>.wasm-function[_bacon]", "<?>.wasm-function[_spam]", "<?>.wasm-function[_parrot]", "(unknown)", "wasmEntry"]);
}
Modified: trunk/JSTests/stress/sampling-profiler-wasm.js (271185 => 271186)
--- trunk/JSTests/stress/sampling-profiler-wasm.js 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/JSTests/stress/sampling-profiler-wasm.js 2021-01-06 03:03:43 UTC (rev 271186)
@@ -8,5 +8,5 @@
var wasmEntry = function() {
return instance.exports.loop(10000000);
};
- runTest(wasmEntry, ["<?>.wasm-function[0]", "wasm-stub", "0", "wasmEntry"]);
+ runTest(wasmEntry, ["<?>.wasm-function[0]", "(unknown)", "wasmEntry"]);
}
Modified: trunk/JSTests/wasm/function-tests/nameSection.js (271185 => 271186)
--- trunk/JSTests/wasm/function-tests/nameSection.js 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/JSTests/wasm/function-tests/nameSection.js 2021-01-06 03:03:43 UTC (rev 271186)
@@ -69,4 +69,4 @@
assert.eq(stacktrace[3], "<?>.wasm-function[_bacon]@[wasm code]");
assert.eq(stacktrace[4], "<?>.wasm-function[_spam]@[wasm code]");
assert.eq(stacktrace[5], "<?>.wasm-function[_parrot]@[wasm code]");
-assert.eq(stacktrace[6], "wasm-stub@[wasm code]"); // wasm entry
+assert.eq(stacktrace[6], "wasm-stub@[native code]"); // wasm entry
Modified: trunk/Source/_javascript_Core/ChangeLog (271185 => 271186)
--- trunk/Source/_javascript_Core/ChangeLog 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-01-06 03:03:43 UTC (rev 271186)
@@ -1,5 +1,37 @@
2021-01-05 Yusuke Suzuki <[email protected]>
+ [JSC] DFG/FTL DirectCall need to respect Wasm IC
+ https://bugs.webkit.org/show_bug.cgi?id=220339
+
+ Reviewed by Saam Barati.
+
+ We found that Wasm IC for fast calls are not used in several places.
+
+ 1. LLInt calls
+ 2. DFG/FTL DirectCall
+ 3. Virtual calls
+
+ We noticed this because of r271112. r271112 made wasm function loading from exports constant-folded in DFG/FTL.
+ And it emits DirectCall instead of Call in DFG/FTL. Then, we missed Wasm IC and get large performance regression
+ in JetStream2 richard-wasm.
+
+ In this patch, we use Wasm IC as much as possible. The key thing of this wasm IC is that it relies on callee.
+ So, if the place is just checking Executable, then we should not go to that IC. Fortunately, the above three checks
+ callee before using code pointer obtained for Wasm IC.
+
+ 1. LLInt call fast path first checks callee.
+ 2. DFG/FTL DirectCall requires callee is constant for wasm functions.
+ 3. Virtual calls are not storing generated codePtr.
+
+ * dfg/DFGOperations.cpp:
+ (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+ * jit/JITOperations.cpp:
+ (JSC::virtualForWithFunction):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::setUpCall):
+
+2021-01-05 Yusuke Suzuki <[email protected]>
+
[WASM] [BigInt] Add I64 to BigInt conversion
https://bugs.webkit.org/show_bug.cgi?id=213528
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (271185 => 271186)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2021-01-06 03:03:43 UTC (rev 271186)
@@ -3550,9 +3550,13 @@
MacroAssemblerCodePtr<JSEntryPtrTag> codePtr;
CodeBlock* codeBlock = nullptr;
- if (executable->isHostFunction())
- codePtr = executable->entrypointFor(kind, MustCheckArity);
- else {
+ if (executable->isHostFunction()) {
+ // jsToWasmICCodePtr assumes that callee is always the same since DirectCall does not check callee.
+ // But for wasm functions, we already ensured that callee is constant when emitting DirectCall.
+ codePtr = jsToWasmICCodePtr(vm, kind, callee);
+ if (!codePtr)
+ codePtr = executable->entrypointFor(kind, MustCheckArity);
+ } else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
RELEASE_ASSERT(isCall(kind) || functionExecutable->constructAbility() != ConstructAbility::CannotConstruct);
Modified: trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (271185 => 271186)
--- trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2021-01-06 03:03:43 UTC (rev 271186)
@@ -917,7 +917,8 @@
ExecutableBase* executable = nullptr;
Edge callee = m_graph.varArgChild(m_node, 0);
CallVariant callVariant;
- if (JSFunction* function = callee->dynamicCastConstant<JSFunction*>(vm())) {
+ JSFunction* function = callee->dynamicCastConstant<JSFunction*>(vm());
+ if (function) {
executable = function->executable();
callVariant = CallVariant(function);
} else if (callee->isFunctionAllocation()) {
@@ -927,6 +928,15 @@
if (!executable)
break;
+
+ // If this is wasm function, and callee is not an constant,
+ // we should not use DirectCall since it will emit Wasm IC based on the assumption that the callee is constant.
+ // Currently, there is no way to reach to this condition (since no function-allocation node generates WebAssemblyFunction),
+ // but this is good guard for the future extension.
+ if (executable->intrinsic() == WasmFunctionIntrinsic) {
+ if (!function)
+ break;
+ }
if (FunctionExecutable* functionExecutable = jsDynamicCast<FunctionExecutable*>(vm(), executable)) {
if (m_node->op() == Construct && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct)
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (271185 => 271186)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2021-01-06 03:03:43 UTC (rev 271186)
@@ -1389,8 +1389,14 @@
reinterpret_cast<void*>(KeepTheFrame));
}
}
- return encodeResult(executable->entrypointFor(
- kind, MustCheckArity).executableAddress(),
+
+ MacroAssemblerCodePtr<JSEntryPtrTag> codePtr;
+ if (executable->isHostFunction())
+ codePtr = jsToWasmICCodePtr(vm, kind, function);
+ if (!codePtr)
+ codePtr = executable->entrypointFor(kind, MustCheckArity);
+
+ return encodeResult(codePtr.executableAddress(),
reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
}
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (271185 => 271186)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2021-01-06 03:03:43 UTC (rev 271186)
@@ -60,6 +60,7 @@
#include "ObjectPropertyConditionSet.h"
#include "ProtoCallFrameInlines.h"
#include "RegExpObject.h"
+#include "Repatch.h"
#include "ShadowChicken.h"
#include "SuperSampler.h"
#include "VMInlines.h"
@@ -1736,9 +1737,13 @@
MacroAssemblerCodePtr<JSEntryPtrTag> codePtr;
CodeBlock* codeBlock = nullptr;
- if (executable->isHostFunction())
- codePtr = executable->entrypointFor(kind, MustCheckArity);
- else {
+ if (executable->isHostFunction()) {
+#if ENABLE(JIT)
+ codePtr = jsToWasmICCodePtr(vm, kind, callee);
+#endif
+ if (!codePtr)
+ codePtr = executable->entrypointFor(kind, MustCheckArity);
+ } else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct)
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.cpp (271185 => 271186)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.cpp 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.cpp 2021-01-06 03:03:43 UTC (rev 271186)
@@ -337,6 +337,8 @@
return "DataViewSetFloat32";
case DataViewSetFloat64:
return "DataViewSetFloat64";
+ case WasmFunctionIntrinsic:
+ return "WasmFunctionIntrinsic";
}
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.h (271185 => 271186)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.h 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.h 2021-01-06 03:03:43 UTC (rev 271186)
@@ -192,6 +192,8 @@
DataViewSetUint32,
DataViewSetFloat32,
DataViewSetFloat64,
+
+ WasmFunctionIntrinsic,
};
Optional<IterationKind> interationKindForIntrinsic(Intrinsic);
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp (271185 => 271186)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp 2021-01-06 02:27:58 UTC (rev 271185)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp 2021-01-06 03:03:43 UTC (rev 271186)
@@ -434,7 +434,7 @@
WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, Structure* structure, unsigned length, const String& name, JSWebAssemblyInstance* instance, Wasm::Callee& jsEntrypoint, Wasm::WasmToWasmImportableFunction::LoadLocation wasmToWasmEntrypointLoadLocation, Wasm::SignatureIndex signatureIndex)
{
- NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name);
+ NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, WasmFunctionIntrinsic, callHostFunctionAsConstructor, nullptr, name);
WebAssemblyFunction* function = new (NotNull, allocateCell<WebAssemblyFunction>(vm.heap)) WebAssemblyFunction(vm, executable, globalObject, structure, jsEntrypoint, wasmToWasmEntrypointLoadLocation, signatureIndex);
function->finishCreation(vm, executable, length, name, instance);
return function;