Commit f4f8f247 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm][perf-bug] Fix perf regression due to expensive subtyping check

The more complicated subtyping checks due to the new wasm-gc types
caused a performance regression. This CL:
- Adds a V8_LIKELY annotation to the more common path
  (type equality).
- Factors the rest of the check out of the inlinable part of subtype
  checking to reduce binary size, and thus cache misses.

Bug: chromium:1096769, v8:7748
Change-Id: Idd92789b40cc175c268ef5a53f042d4b881992af
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2263156
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68511}
parent dd584721
......@@ -132,26 +132,38 @@ bool IsArraySubtype(uint32_t subtype_index, uint32_t supertype_index,
} // namespace
// TODO(7748): Extend this with function and any-heap subtyping.
V8_EXPORT_PRIVATE bool IsSubtypeOfHeap(HeapType subtype, HeapType supertype,
const WasmModule* module) {
DCHECK(!module->has_signature(subtype) && !module->has_signature(supertype));
if (subtype == supertype) {
V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(ValueType subtype,
ValueType supertype,
const WasmModule* module) {
bool compatible_references = (subtype.kind() == ValueType::kOptRef &&
supertype.kind() == ValueType::kOptRef) ||
(subtype.kind() == ValueType::kRef &&
(supertype.kind() == ValueType::kOptRef ||
supertype.kind() == ValueType::kRef));
if (!compatible_references) return false;
HeapType sub_heap = subtype.heap_type();
HeapType super_heap = supertype.heap_type();
DCHECK(!module->has_signature(sub_heap) &&
!module->has_signature(super_heap));
if (sub_heap == super_heap) {
return true;
}
// eqref is a supertype of all reference types except funcref.
if (supertype == kHeapEq) {
return subtype != kHeapFunc;
if (super_heap == kHeapEq) {
return sub_heap != kHeapFunc;
}
// At the moment, generic heap types are not subtyping-related otherwise.
if (is_generic_heap_type(subtype) || is_generic_heap_type(supertype)) {
if (is_generic_heap_type(sub_heap) || is_generic_heap_type(super_heap)) {
return false;
}
if (module->is_cached_subtype(subtype, supertype)) {
if (module->is_cached_subtype(sub_heap, super_heap)) {
return true;
}
return IsStructSubtype(subtype, supertype, module) ||
IsArraySubtype(subtype, supertype, module);
return IsStructSubtype(sub_heap, super_heap, module) ||
IsArraySubtype(sub_heap, super_heap, module);
}
// TODO(7748): Extend this with function subtyping.
......
......@@ -12,8 +12,9 @@ namespace internal {
namespace wasm {
struct WasmModule;
V8_EXPORT_PRIVATE bool IsSubtypeOfHeap(HeapType subtype, HeapType supertype,
const WasmModule* module);
V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(ValueType subtype,
ValueType supertype,
const WasmModule* module);
// The subtyping between value types is described by the following rules:
// - All types are a supertype of bottom.
......@@ -22,15 +23,8 @@ V8_EXPORT_PRIVATE bool IsSubtypeOfHeap(HeapType subtype, HeapType supertype,
// - ref(ht1) <: ref/optref(ht2) iff ht1 <: ht2.
V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
const WasmModule* module) {
if (subtype == supertype) return true;
bool compatible_references = (subtype.kind() == ValueType::kRef &&
supertype.kind() == ValueType::kRef) ||
(subtype.kind() == ValueType::kRef &&
supertype.kind() == ValueType::kOptRef) ||
(subtype.kind() == ValueType::kOptRef &&
supertype.kind() == ValueType::kOptRef);
if (!compatible_references) return false;
return IsSubtypeOfHeap(subtype.heap_type(), supertype.heap_type(), module);
if (V8_LIKELY(subtype == supertype)) return true;
return IsSubtypeOfImpl(subtype, supertype, module);
}
ValueType CommonSubtype(ValueType a, ValueType b, const WasmModule* module);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment