[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: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#76216}
This commit is contained in:
parent
5612424a13
commit
db8b90283a
@ -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;
|
||||
|
||||
NativeContextRef native_context = broker()->target_native_context();
|
||||
if (!equals(native_context.GetInitialJSArrayMap(current_kind))) return {};
|
||||
base::Optional<Map> maybe_result = Map::TryAsElementsKind(
|
||||
broker()->isolate(), object(), kind, ConcurrencyMode::kConcurrent);
|
||||
|
||||
return native_context.GetInitialJSArrayMap(kind);
|
||||
#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))) {
|
||||
CHECK_EQ(Map::TryAsElementsKind(broker()->isolate(), object(), kind,
|
||||
ConcurrencyMode::kConcurrent)
|
||||
.value(),
|
||||
*native_context.GetInitialJSArrayMap(kind).object());
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user