Commit 286747bb authored by Richard Stotz's avatar Richard Stotz Committed by V8 LUCI CQ

[wasm] Remove CallRefData

This CL removes the CallRefData data structure and accesses a funcref's
target and instance through the funcref.

Bug: v8:7748
Change-Id: Ic46b127f7775052d5df13b03c447e3b15328ad74
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3306486
Commit-Queue: Richard Stotz <rstz@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78194}
parent 574d4a8b
......@@ -488,20 +488,23 @@ macro GetTargetAndInstance(funcref: WasmInternalFunction): TargetAndInstance {
// Two slots per call_ref instruction. These slots' values can be:
// - uninitialized: (undefined, <unused>). Note: we use {undefined} as the
// sentinel as an optimization, as it's the default value for FixedArrays.
// - monomorphic: (funcref, call_ref_data)
// - monomorphic: (funcref, count (smi)). The second slot is a counter for how
// often the funcref in the first slot has been seen.
// - polymorphic: (fixed_array, <unused>). In this case, the array
// contains 2..4 pairs (funcref, call_ref_data) (like monomorphic data).
// contains 2..4 pairs (funcref, count (smi)) (like monomorphic data).
// - megamorphic: ("megamorphic" sentinel, <unused>)
//
// TODO(rstz): The counter might overflow if it exceeds the range of a Smi.
// This can lead to incorrect inlining decisions.
builtin CallRefIC(
vector: FixedArray, index: intptr,
funcref: WasmInternalFunction): TargetAndInstance {
const value = vector.objects[index];
if (value == funcref) {
// Monomorphic hit. Check for this case first to maximize its performance.
const data = UnsafeCast<CallRefData>(vector.objects[index + 1]);
data.count = data.count + 1;
return TargetAndInstance{target: data.target, instance: data.instance};
const count = UnsafeCast<Smi>(vector.objects[index + 1]) + SmiConstant(1);
vector.objects[index + 1] = count;
return GetTargetAndInstance(funcref);
}
// Check for polymorphic hit; its performance is second-most-important.
if (Is<FixedArray>(value)) {
......@@ -509,9 +512,9 @@ builtin CallRefIC(
for (let i: intptr = 0; i < entries.length_intptr; i += 2) {
if (entries.objects[i] == funcref) {
// Polymorphic hit.
const data = UnsafeCast<CallRefData>(entries.objects[i + 1]);
data.count = data.count + 1;
return TargetAndInstance{target: data.target, instance: data.instance};
const count = UnsafeCast<Smi>(entries.objects[i + 1]) + SmiConstant(1);
vector.objects[i + 1] = count;
return GetTargetAndInstance(funcref);
}
}
}
......@@ -519,10 +522,8 @@ builtin CallRefIC(
// instance. They all fall through to returning the computed data.
const result = GetTargetAndInstance(funcref);
if (TaggedEqual(value, Undefined)) {
const data = new
CallRefData{instance: result.instance, target: result.target, count: 1};
vector.objects[index] = funcref;
vector.objects[index + 1] = data;
vector.objects[index + 1] = SmiConstant(1);
} else if (Is<FixedArray>(value)) {
// Polymorphic miss.
const entries = UnsafeCast<FixedArray>(value);
......@@ -530,8 +531,6 @@ builtin CallRefIC(
vector.objects[index] = ic::kMegamorphicSymbol;
vector.objects[index + 1] = ic::kMegamorphicSymbol;
} else {
const data = new
CallRefData{instance: result.instance, target: result.target, count: 1};
const newEntries = UnsafeCast<FixedArray>(AllocateFixedArray(
ElementsKind::PACKED_ELEMENTS, entries.length_intptr + 2,
AllocationFlag::kNone));
......@@ -540,22 +539,20 @@ builtin CallRefIC(
}
const newIndex = entries.length_intptr;
newEntries.objects[newIndex] = funcref;
newEntries.objects[newIndex + 1] = data;
newEntries.objects[newIndex + 1] = SmiConstant(1);
vector.objects[index] = newEntries;
}
} else if (Is<WasmInternalFunction>(value)) {
// Monomorphic miss.
const data = new
CallRefData{instance: result.instance, target: result.target, count: 1};
const newEntries = UnsafeCast<FixedArray>(AllocateFixedArray(
ElementsKind::PACKED_ELEMENTS, 4, AllocationFlag::kNone));
newEntries.objects[0] = value;
newEntries.objects[1] = vector.objects[index + 1];
newEntries.objects[2] = funcref;
newEntries.objects[3] = data;
newEntries.objects[3] = SmiConstant(1);
vector.objects[index] = newEntries;
// Clear the old pointer to the first entry's data object; the specific
// value we write doesn't matter.
// Clear the first entry's counter; the specific value we write doesn't
// matter.
vector.objects[index + 1] = Undefined;
}
// The "ic::IsMegamorphic(value)" case doesn't need to do anything.
......
......@@ -1267,9 +1267,8 @@ std::vector<CallSiteFeedback> ProcessTypeFeedback(
PrintF("[Function #%d call_ref #%d inlineable (monomorphic)]\n",
func_index, i / 2);
}
CallRefData data = CallRefData::cast(feedback.get(i + 1));
result[i / 2] = {target.function_index(),
static_cast<int>(data.count())};
int32_t count = Smi::cast(feedback.get(i + 1)).value();
result[i / 2] = {target.function_index(), count};
continue;
}
} else if (value.IsFixedArray()) {
......@@ -1279,13 +1278,13 @@ std::vector<CallSiteFeedback> ProcessTypeFeedback(
FixedArray polymorphic = FixedArray::cast(value);
size_t total_count = 0;
for (int j = 0; j < polymorphic.length(); j += 2) {
total_count += CallRefData::cast(polymorphic.get(j + 1)).count();
total_count += Smi::cast(polymorphic.get(j + 1)).value();
}
int found_target = -1;
int found_count = -1;
double best_frequency = 0;
for (int j = 0; j < polymorphic.length(); j += 2) {
uint32_t this_count = CallRefData::cast(polymorphic.get(j + 1)).count();
int32_t this_count = Smi::cast(polymorphic.get(j + 1)).value();
double frequency = static_cast<double>(this_count) / total_count;
if (frequency > best_frequency) best_frequency = frequency;
if (frequency < 0.8) continue;
......
......@@ -194,10 +194,3 @@ extern class WasmArray extends WasmObject {
@if(TAGGED_SIZE_8_BYTES) optional_padding: uint32;
@ifnot(TAGGED_SIZE_8_BYTES) optional_padding: void;
}
@export
class CallRefData extends HeapObject {
instance: HeapObject;
target: RawPtr;
count: uint32;
}
This diff is collapsed.
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