Commit db8b9028 authored by Jakob Gruber's avatar Jakob Gruber Committed by V8 LUCI CQ

[compiler] Reimplement AsElementsKind transition walk

MapRef::AsElementsKind can now concurrently walk transitions to find a
map of the requested elements kind.

Note this implementation is still less powerful than what we had before
crrev.com/c/3021175, since we never allocate new maps. When the
transition walk fails to find an appropriate map, we bail out.

I don't expect this to be a problem - when optimizing, the code has
already run multiple times and transitioned maps should exist.

Bug: v8:7790, v8:11988
Change-Id: Ic767b40c29bb86f7c4167097c76c5417985420fb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3086471
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76216}
parent 5612424a
......@@ -1816,17 +1816,29 @@ INSTANCE_TYPE_CHECKERS(DEF_TESTER)
#undef DEF_TESTER
base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const {
// TODO(jgruber): Consider supporting transitions other than for JSArray
// initial maps (e.g. by walking transitions concurrently and finding an
// existing map that fits).
const ElementsKind current_kind = elements_kind();
if (kind == current_kind) return *this;
base::Optional<Map> maybe_result = Map::TryAsElementsKind(
broker()->isolate(), object(), kind, ConcurrencyMode::kConcurrent);
#ifdef DEBUG
// If starting from an initial JSArray map, TryAsElementsKind must succeed
// and return the expected transitioned JSArray map.
NativeContextRef native_context = broker()->target_native_context();
if (!equals(native_context.GetInitialJSArrayMap(current_kind))) return {};
if (equals(native_context.GetInitialJSArrayMap(current_kind))) {
CHECK_EQ(Map::TryAsElementsKind(broker()->isolate(), object(), kind,
ConcurrencyMode::kConcurrent)
.value(),
*native_context.GetInitialJSArrayMap(kind).object());
}
#endif // DEBUG
return native_context.GetInitialJSArrayMap(kind);
if (!maybe_result.has_value()) {
TRACE_BROKER_MISSING(broker(), "MapRef::AsElementsKind " << *this);
return {};
}
return MakeRefAssumeMemoryFence(broker(), maybe_result.value());
}
void MapRef::SerializeForElementStore(NotConcurrentInliningTag tag) {
......
......@@ -1127,6 +1127,15 @@ static Handle<Map> AddMissingElementsTransitions(Isolate* isolate,
return current_map;
}
// static
base::Optional<Map> Map::TryAsElementsKind(Isolate* isolate, Handle<Map> map,
ElementsKind kind,
ConcurrencyMode cmode) {
Map closest_map = FindClosestElementsTransition(isolate, *map, kind, cmode);
if (closest_map.elements_kind() != kind) return {};
return closest_map;
}
// static
Handle<Map> Map::AsElementsKind(Isolate* isolate, Handle<Map> map,
ElementsKind kind) {
......
......@@ -701,6 +701,10 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
static Handle<Map> TransitionElementsTo(Isolate* isolate, Handle<Map> map,
ElementsKind to_kind);
static base::Optional<Map> TryAsElementsKind(Isolate* isolate,
Handle<Map> map,
ElementsKind kind,
ConcurrencyMode cmode);
V8_EXPORT_PRIVATE static Handle<Map> AsElementsKind(Isolate* isolate,
Handle<Map> map,
ElementsKind kind);
......
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