[wasm-gc] Canonicalize RTTs created with rtt.sub

When rtt.sub is called repeatedly with the same arguments, it
should return the same result. This CL introduces a cache for
previously created sub-RTTs to achieve that.

Bug: v8:7748
Change-Id: Ie6c74eedf0df6f94cd973fdb0b6b6fc0130a9c41
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2275967
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68715}
This commit is contained in:
Jakob Kummerow 2020-07-07 14:36:00 +02:00 committed by Commit Bot
parent 9b4450da62
commit bc793ae8e5
4 changed files with 44 additions and 0 deletions

View File

@ -1349,12 +1349,14 @@ Handle<Foreign> Factory::NewForeign(Address addr) {
Handle<WasmTypeInfo> Factory::NewWasmTypeInfo(Address type_address,
Handle<Map> parent) {
Handle<ArrayList> subtypes = ArrayList::New(isolate(), 0);
Map map = *wasm_type_info_map();
HeapObject result = AllocateRawWithImmortalMap(map.instance_size(),
AllocationType::kYoung, map);
Handle<WasmTypeInfo> info(WasmTypeInfo::cast(result), isolate());
info->set_foreign_address(isolate(), type_address);
info->set_parent(*parent);
info->set_subtypes(*subtypes);
return info;
}

View File

@ -613,6 +613,7 @@ class WasmTypeInfo::BodyDescriptor final : public BodyDescriptorBase {
Foreign::BodyDescriptor::IterateBody<ObjectVisitor>(map, obj, object_size,
v);
IteratePointer(obj, kParentOffset, v);
IteratePointer(obj, kSubtypesOffset, v);
}
static inline int SizeOf(Map map, HeapObject object) { return kSize; }

View File

@ -493,12 +493,50 @@ RUNTIME_FUNCTION(Runtime_WasmDebugBreak) {
return ReadOnlyRoots(isolate).undefined_value();
}
namespace {
// TODO(7748): Consider storing this array in Maps'
// "transitions_or_prototype_info" slot.
// Also consider being more memory-efficient, e.g. use inline storage for
// single entries, and/or adapt the growth strategy.
class RttSubtypes : public ArrayList {
public:
static Handle<ArrayList> Insert(Isolate* isolate, Handle<ArrayList> array,
uint32_t type_index, Handle<Map> sub_rtt) {
Handle<Smi> key = handle(Smi::FromInt(type_index), isolate);
return Add(isolate, array, key, sub_rtt);
}
static Map SearchSubtype(Handle<ArrayList> array, uint32_t type_index) {
// Linear search for now.
// TODO(7748): Consider keeping the array sorted and using binary search
// here, if empirical data indicates that that would be worthwhile.
int count = array->Length();
for (int i = 0; i < count; i += 2) {
if (Smi::cast(array->get(i)).value() == static_cast<int>(type_index)) {
return Map::cast(array->get(i + 1));
}
}
return {};
}
};
} // namespace
RUNTIME_FUNCTION(Runtime_WasmAllocateRtt) {
ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_UINT32_ARG_CHECKED(type_index, 0);
CONVERT_ARG_HANDLE_CHECKED(Map, parent, 1);
// Check for an existing RTT first.
// TODO(7748): Support {parent} RTTs for generic heap types ("eqref" etc).
DCHECK(parent->IsWasmStructMap() || parent->IsWasmArrayMap());
Handle<ArrayList> cache(parent->wasm_type_info().subtypes(), isolate);
Map maybe_cached = RttSubtypes::SearchSubtype(cache, type_index);
if (!maybe_cached.is_null()) return maybe_cached;
// Allocate a fresh RTT otherwise.
Handle<WasmInstanceObject> instance(GetWasmInstanceOnStackTop(isolate),
isolate);
const wasm::WasmModule* module = instance->module();
@ -510,6 +548,8 @@ RUNTIME_FUNCTION(Runtime_WasmAllocateRtt) {
} else {
UNREACHABLE();
}
cache = RttSubtypes::Insert(isolate, cache, type_index, rtt);
parent->wasm_type_info().set_subtypes(*cache);
return *rtt;
}

View File

@ -95,6 +95,7 @@ extern class AsmWasmData extends Struct {
@generateCppClass
extern class WasmTypeInfo extends Foreign {
parent: Map;
subtypes: ArrayList;
}
@generateCppClass