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

[heap-refs] Make the return type of MapRef::prototype non-optional

We are guaranteed to have a valid ref for the prototype now that the
no-concurrent-inlining configuration has been removed.

Bug: v8:7790
Change-Id: I8400d1887f5cd41b14c92c87151847c0ed78f911
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3394708Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78648}
parent 5f3ff431
......@@ -910,18 +910,17 @@ PropertyAccessInfo AccessInfoFactory::ComputePropertyAccessInfo(
// Walk up the prototype chain.
// Load the map's prototype's map to guarantee that every time we use it,
// we use the same Map.
base::Optional<HeapObjectRef> prototype = map.prototype();
if (!prototype.has_value()) return Invalid();
HeapObjectRef prototype = map.prototype();
MapRef map_prototype_map = prototype->map();
MapRef map_prototype_map = prototype.map();
if (!map_prototype_map.object()->IsJSObjectMap()) {
// Don't allow proxies on the prototype chain.
if (!prototype->IsNull()) {
DCHECK(prototype->object()->IsJSProxy());
if (!prototype.IsNull()) {
DCHECK(prototype.object()->IsJSProxy());
return Invalid();
}
DCHECK(prototype->IsNull());
DCHECK(prototype.IsNull());
if (dictionary_prototype_on_chain) {
// TODO(v8:11248) See earlier comment about
......@@ -945,7 +944,7 @@ PropertyAccessInfo AccessInfoFactory::ComputePropertyAccessInfo(
return PropertyAccessInfo::NotFound(zone(), receiver_map, holder);
}
holder = prototype->AsJSObject();
holder = prototype.AsJSObject();
map = map_prototype_map;
if (!CanInlinePropertyAccess(map, access_mode)) {
......
......@@ -1232,7 +1232,7 @@ namespace {
void DependOnStablePrototypeChain(CompilationDependencies* deps, MapRef map,
base::Optional<JSObjectRef> last_prototype) {
while (true) {
HeapObjectRef proto = map.prototype().value();
HeapObjectRef proto = map.prototype();
if (!proto.IsJSObject()) {
CHECK_EQ(proto.map().oddball_type(), OddballType::kNull);
break;
......
......@@ -1097,14 +1097,14 @@ base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const {
bool MapRef::HasOnlyStablePrototypesWithFastElements(
ZoneVector<MapRef>* prototype_maps) {
DCHECK_NOT_NULL(prototype_maps);
MapRef prototype_map = prototype().value().map();
MapRef prototype_map = prototype().map();
while (prototype_map.oddball_type() != OddballType::kNull) {
if (!prototype_map.IsJSObjectMap() || !prototype_map.is_stable() ||
!IsFastElementsKind(prototype_map.elements_kind())) {
return false;
}
prototype_maps->push_back(prototype_map);
prototype_map = prototype_map.prototype().value().map();
prototype_map = prototype_map.prototype().map();
}
return true;
}
......@@ -1530,13 +1530,13 @@ HolderLookupResult FunctionTemplateInfoRef::LookupHolderOfExpectedType(
if (!receiver_map.IsJSGlobalProxyMap()) return not_found;
}
base::Optional<HeapObjectRef> prototype = receiver_map.prototype();
if (!prototype.has_value() || prototype->IsNull()) return not_found;
if (!expected_receiver_type->IsTemplateFor(prototype->object()->map())) {
HeapObjectRef prototype = receiver_map.prototype();
if (prototype.IsNull()) return not_found;
if (!expected_receiver_type->IsTemplateFor(prototype.object()->map())) {
return not_found;
}
return HolderLookupResult(CallOptimization::kHolderFound,
prototype->AsJSObject());
prototype.AsJSObject());
}
ObjectRef CallHandlerInfoRef::data() const {
......@@ -1595,9 +1595,9 @@ DescriptorArrayRef MapRef::instance_descriptors() const {
object()->instance_descriptors(broker()->isolate(), kAcquireLoad));
}
base::Optional<HeapObjectRef> MapRef::prototype() const {
return TryMakeRef(broker(), HeapObject::cast(object()->prototype()),
kAssumeMemoryFence);
HeapObjectRef MapRef::prototype() const {
return MakeRefAssumeMemoryFence(broker(),
HeapObject::cast(object()->prototype()));
}
MapRef MapRef::FindRootMap() const {
......@@ -2223,9 +2223,8 @@ bool PropertyCellRef::Cache() const {
}
bool NativeContextRef::GlobalIsDetached() const {
base::Optional<ObjectRef> proxy_proto =
global_proxy_object().map().prototype();
return !proxy_proto.has_value() || !proxy_proto->equals(global_object());
ObjectRef proxy_proto = global_proxy_object().map().prototype();
return !proxy_proto.equals(global_object());
}
base::Optional<PropertyCellRef> JSGlobalObjectRef::GetPropertyCell(
......
......@@ -710,7 +710,7 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
HeapObjectRef GetBackPointer() const;
base::Optional<HeapObjectRef> prototype() const;
HeapObjectRef prototype() const;
bool HasOnlyStablePrototypesWithFastElements(
ZoneVector<MapRef>* prototype_maps);
......
......@@ -2628,16 +2628,13 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) {
MapRef first_receiver_map = receiver_maps[0];
bool const is_constructor = first_receiver_map.is_constructor();
base::Optional<HeapObjectRef> const prototype =
first_receiver_map.prototype();
if (!prototype.has_value()) return inference.NoChange();
HeapObjectRef prototype = first_receiver_map.prototype();
for (const MapRef& receiver_map : receiver_maps) {
base::Optional<HeapObjectRef> map_prototype = receiver_map.prototype();
if (!map_prototype.has_value()) return inference.NoChange();
HeapObjectRef map_prototype = receiver_map.prototype();
// Check for consistency among the {receiver_maps}.
if (!map_prototype->equals(*prototype) ||
if (!map_prototype.equals(prototype) ||
receiver_map.is_constructor() != is_constructor ||
!InstanceTypeChecker::IsJSFunctionOrBoundFunction(
receiver_map.instance_type())) {
......@@ -2690,7 +2687,7 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) {
MapRef map = is_constructor
? native_context().bound_function_with_constructor_map()
: native_context().bound_function_without_constructor_map();
if (!map.prototype().value().equals(*prototype)) return inference.NoChange();
if (!map.prototype().equals(prototype)) return inference.NoChange();
inference.RelyOnMapsPreferStability(dependencies(), jsgraph(), &effect,
control, p.feedback());
......@@ -2813,16 +2810,14 @@ Reduction JSCallReducer::ReduceObjectGetPrototype(Node* node, Node* object) {
ZoneVector<MapRef> const& object_maps = inference.GetMaps();
MapRef candidate_map = object_maps[0];
base::Optional<HeapObjectRef> candidate_prototype = candidate_map.prototype();
if (!candidate_prototype.has_value()) return inference.NoChange();
HeapObjectRef candidate_prototype = candidate_map.prototype();
// Check if we can constant-fold the {candidate_prototype}.
for (size_t i = 0; i < object_maps.size(); ++i) {
MapRef object_map = object_maps[i];
base::Optional<HeapObjectRef> map_prototype = object_map.prototype();
if (!map_prototype.has_value()) return inference.NoChange();
HeapObjectRef map_prototype = object_map.prototype();
if (IsSpecialReceiverInstanceType(object_map.instance_type()) ||
!map_prototype->equals(*candidate_prototype)) {
!map_prototype.equals(candidate_prototype)) {
// We exclude special receivers, like JSProxy or API objects that
// might require access checks here; we also don't want to deal
// with hidden prototypes at this point.
......@@ -2835,7 +2830,7 @@ Reduction JSCallReducer::ReduceObjectGetPrototype(Node* node, Node* object) {
if (!inference.RelyOnMapsViaStability(dependencies())) {
return inference.NoChange();
}
Node* value = jsgraph()->Constant(*candidate_prototype);
Node* value = jsgraph()->Constant(candidate_prototype);
ReplaceWithValue(node, value);
return Replace(value);
}
......@@ -6855,9 +6850,8 @@ bool JSCallReducer::DoPromiseChecks(MapInference* inference) {
// have the initial Promise.prototype as their [[Prototype]].
for (const MapRef& receiver_map : receiver_maps) {
if (!receiver_map.IsJSPromiseMap()) return false;
base::Optional<HeapObjectRef> prototype = receiver_map.prototype();
if (!prototype.has_value() ||
!prototype->equals(native_context().promise_prototype())) {
HeapObjectRef prototype = receiver_map.prototype();
if (!prototype.equals(native_context().promise_prototype())) {
return false;
}
}
......
......@@ -1328,7 +1328,7 @@ base::Optional<MapRef> GetObjectCreateMap(JSHeapBroker* broker,
MapRef standard_map =
broker->target_native_context().object_function().initial_map(
broker->dependencies());
if (prototype.equals(standard_map.prototype().value())) {
if (prototype.equals(standard_map.prototype())) {
return standard_map;
}
if (prototype.map().oddball_type() == OddballType::kNull) {
......
......@@ -365,15 +365,14 @@ Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor(
}
JSFunctionRef function = m.Ref(broker()).AsJSFunction();
MapRef function_map = function.map();
base::Optional<HeapObjectRef> function_prototype = function_map.prototype();
if (!function_prototype.has_value()) return NoChange();
HeapObjectRef function_prototype = function_map.prototype();
// We can constant-fold the super constructor access if the
// {function}s map is stable, i.e. we can use a code dependency
// to guard against [[Prototype]] changes of {function}.
if (function_map.is_stable()) {
dependencies()->DependOnStableMap(function_map);
Node* value = jsgraph()->Constant(*function_prototype);
Node* value = jsgraph()->Constant(function_prototype);
ReplaceWithValue(node, value);
return Replace(value);
}
......@@ -540,13 +539,12 @@ JSNativeContextSpecialization::InferHasInPrototypeChain(
all = false;
break;
}
base::Optional<HeapObjectRef> map_prototype = map.prototype();
if (!map_prototype.has_value()) return kMayBeInPrototypeChain;
if (map_prototype->equals(prototype)) {
HeapObjectRef map_prototype = map.prototype();
if (map_prototype.equals(prototype)) {
none = false;
break;
}
map = map_prototype->map();
map = map_prototype.map();
// TODO(v8:11457) Support dictionary mode protoypes here.
if (!map.is_stable() || map.is_dictionary_map()) {
return kMayBeInPrototypeChain;
......@@ -3411,7 +3409,7 @@ bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
// or Object.prototype objects as their prototype (in any of the current
// native contexts, as the global Array protector works isolate-wide).
for (MapRef receiver_map : receiver_maps) {
ObjectRef receiver_prototype = receiver_map.prototype().value();
ObjectRef receiver_prototype = receiver_map.prototype();
if (!receiver_prototype.IsJSObject() ||
!broker()->IsArrayOrObjectPrototype(receiver_prototype.AsJSObject())) {
return false;
......
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