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

[compiler] Refify more of the compiler

Convert more raw Handle<Map> uses to MapRef.

Bug: v8:7790
Change-Id: Id638b70607aa5a73404ee37dfda5e038018be525
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067337
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarSantiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76089}
parent ed75c0ad
......@@ -250,6 +250,10 @@ class V8_EXPORT_PRIVATE ObjectRef {
JSHeapBroker* broker_;
};
template <class T>
using ZoneRefUnorderedSet =
ZoneUnorderedSet<T, ObjectRef::Hash, ObjectRef::Equal>;
// Temporary class that carries information from a Map. We'd like to remove
// this class and use MapRef instead, but we can't as long as we support the
// kDisabled broker mode. That's because obtaining the MapRef via
......
This diff is collapsed.
......@@ -250,36 +250,37 @@ ElementAccessFeedback::transition_groups() const {
}
ElementAccessFeedback const& ElementAccessFeedback::Refine(
ZoneVector<Handle<Map>> const& inferred_maps, Zone* zone) const {
JSHeapBroker* broker, ZoneVector<MapRef> const& inferred_maps) const {
ElementAccessFeedback& refined_feedback =
*zone->New<ElementAccessFeedback>(zone, keyed_mode(), slot_kind());
*broker->zone()->New<ElementAccessFeedback>(broker->zone(), keyed_mode(),
slot_kind());
if (inferred_maps.empty()) return refined_feedback;
ZoneUnorderedSet<Handle<Map>, Handle<Map>::hash, Handle<Map>::equal_to>
inferred(zone);
ZoneRefUnorderedSet<MapRef> inferred(broker->zone());
inferred.insert(inferred_maps.begin(), inferred_maps.end());
for (auto const& group : transition_groups()) {
DCHECK(!group.empty());
TransitionGroup new_group(zone);
TransitionGroup new_group(broker->zone());
for (size_t i = 1; i < group.size(); ++i) {
Handle<Map> source = group[i];
MapRef source = MakeRefAssumeMemoryFence(broker, *group[i]);
if (inferred.find(source) != inferred.end()) {
new_group.push_back(source);
new_group.push_back(source.object());
}
}
Handle<Map> target = group.front();
MapRef target = MakeRefAssumeMemoryFence(broker, *group.front());
bool const keep_target =
inferred.find(target) != inferred.end() || new_group.size() > 1;
if (keep_target) {
new_group.push_back(target);
new_group.push_back(target.object());
// The target must be at the front, the order of sources doesn't matter.
std::swap(new_group[0], new_group[new_group.size() - 1]);
}
if (!new_group.empty()) {
DCHECK(new_group.size() == 1 || new_group.front().equals(target));
DCHECK(new_group.size() == 1 ||
new_group.front().equals(target.object()));
refined_feedback.transition_groups_.push_back(std::move(new_group));
}
}
......
......@@ -679,7 +679,7 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
// passed into this node has to be the callees context (loaded above).
if (node->opcode() == IrOpcode::kJSCall &&
is_sloppy(shared_info->language_mode()) && !shared_info->native()) {
Node* effect = NodeProperties::GetEffectInput(node);
Effect effect{NodeProperties::GetEffectInput(node)};
if (NodeProperties::CanBePrimitive(broker(), call.receiver(), effect)) {
CallParameters const& p = CallParametersOf(node->op());
Node* global_proxy = jsgraph()->Constant(
......
......@@ -212,16 +212,14 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
// code dependencies and might use the array protector cell.
bool CanTreatHoleAsUndefined(ZoneVector<MapRef> const& receiver_maps);
void RemoveImpossibleMaps(Node* object, ZoneVector<Handle<Map>>* maps) const;
void RemoveImpossibleMaps(Node* object, ZoneVector<MapRef>* maps) const;
ElementAccessFeedback const& TryRefineElementAccessFeedback(
ElementAccessFeedback const& feedback, Node* receiver,
Node* effect) const;
Effect effect) const;
// Try to infer maps for the given {object} at the current {effect}.
bool InferMaps(Node* object, Node* effect,
ZoneVector<Handle<Map>>* maps) const;
bool InferMaps(Node* object, Effect effect, ZoneVector<MapRef>* maps) const;
// Try to infer a root map for the {object} independent of the current program
// location.
......@@ -236,7 +234,7 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
kMayBeInPrototypeChain
};
InferHasInPrototypeChainResult InferHasInPrototypeChain(
Node* receiver, Node* effect, HeapObjectRef const& prototype);
Node* receiver, Effect effect, HeapObjectRef const& prototype);
Node* BuildLoadPrototypeFromObject(Node* object, Node* effect, Node* control);
......
......@@ -9,15 +9,14 @@
#include "src/compiler/js-graph.h"
#include "src/compiler/simplified-operator.h"
#include "src/objects/map-inl.h"
#include "src/zone/zone-handle-set.h"
namespace v8 {
namespace internal {
namespace compiler {
MapInference::MapInference(JSHeapBroker* broker, Node* object, Node* effect)
: broker_(broker), object_(object) {
ZoneHandleSet<Map> maps;
MapInference::MapInference(JSHeapBroker* broker, Node* object, Effect effect)
: broker_(broker), object_(object), maps_(broker->zone()) {
ZoneRefUnorderedSet<MapRef> maps(broker->zone());
auto result =
NodeProperties::InferMapsUnsafe(broker_, object_, effect, &maps);
maps_.insert(maps_.end(), maps.begin(), maps.end());
......@@ -67,9 +66,8 @@ bool MapInference::AllOfInstanceTypesUnsafe(
std::function<bool(InstanceType)> f) const {
CHECK(HaveMaps());
auto instance_type = [this, f](Handle<Map> map) {
MapRef map_ref = MakeRef(broker_, map);
return f(map_ref.instance_type());
auto instance_type = [f](const MapRef& map) {
return f(map.instance_type());
};
return std::all_of(maps_.begin(), maps_.end(), instance_type);
}
......@@ -78,22 +76,21 @@ bool MapInference::AnyOfInstanceTypesUnsafe(
std::function<bool(InstanceType)> f) const {
CHECK(HaveMaps());
auto instance_type = [this, f](Handle<Map> map) {
MapRef map_ref = MakeRef(broker_, map);
return f(map_ref.instance_type());
auto instance_type = [f](const MapRef& map) {
return f(map.instance_type());
};
return std::any_of(maps_.begin(), maps_.end(), instance_type);
}
MapHandles const& MapInference::GetMaps() {
ZoneVector<MapRef> const& MapInference::GetMaps() {
SetNeedGuardIfUnreliable();
return maps_;
}
bool MapInference::Is(Handle<Map> expected_map) {
bool MapInference::Is(const MapRef& expected_map) {
if (!HaveMaps()) return false;
const MapHandles& maps = GetMaps();
const ZoneVector<MapRef>& maps = GetMaps();
if (maps.size() != 1) return false;
return maps[0].equals(expected_map);
}
......@@ -104,7 +101,9 @@ void MapInference::InsertMapChecks(JSGraph* jsgraph, Effect* effect,
CHECK(HaveMaps());
CHECK(feedback.IsValid());
ZoneHandleSet<Map> maps;
for (Handle<Map> map : maps_) maps.insert(map, jsgraph->graph()->zone());
for (const MapRef& map : maps_) {
maps.insert(map.object(), jsgraph->graph()->zone());
}
*effect = jsgraph->graph()->NewNode(
jsgraph->simplified()->CheckMaps(CheckMapsFlag::kNone, maps, feedback),
object_, *effect, control);
......@@ -133,14 +132,11 @@ bool MapInference::RelyOnMapsHelper(CompilationDependencies* dependencies,
const FeedbackSource& feedback) {
if (Safe()) return true;
auto is_stable = [this](Handle<Map> map) {
MapRef map_ref = MakeRef(broker_, map);
return map_ref.is_stable();
};
auto is_stable = [](const MapRef& map) { return map.is_stable(); };
if (dependencies != nullptr &&
std::all_of(maps_.cbegin(), maps_.cend(), is_stable)) {
for (Handle<Map> map : maps_) {
dependencies->DependOnStableMap(MakeRef(broker_, map));
for (const MapRef& map : maps_) {
dependencies->DependOnStableMap(map);
}
SetGuarded();
return true;
......
......@@ -34,7 +34,7 @@ class Node;
// reliable).
class MapInference {
public:
MapInference(JSHeapBroker* broker, Node* object, Node* effect);
MapInference(JSHeapBroker* broker, Node* object, Effect effect);
// The destructor checks that the information has been made reliable (if
// necessary) and force-crashes if not.
......@@ -52,10 +52,10 @@ class MapInference {
// These queries require a guard. (Even instance types are generally not
// reliable because of how the representation of a string can change.)
V8_WARN_UNUSED_RESULT MapHandles const& GetMaps();
V8_WARN_UNUSED_RESULT ZoneVector<MapRef> const& GetMaps();
V8_WARN_UNUSED_RESULT bool AllOfInstanceTypes(
std::function<bool(InstanceType)> f);
V8_WARN_UNUSED_RESULT bool Is(Handle<Map> expected_map);
V8_WARN_UNUSED_RESULT bool Is(const MapRef& expected_map);
// These methods provide a guard.
//
......@@ -83,7 +83,7 @@ class MapInference {
JSHeapBroker* const broker_;
Node* const object_;
MapHandles maps_;
ZoneVector<MapRef> maps_;
enum {
kReliableOrGuarded,
kUnreliableDontNeedGuard,
......
......@@ -345,10 +345,32 @@ base::Optional<MapRef> NodeProperties::GetJSCreateMap(JSHeapBroker* broker,
return base::nullopt;
}
namespace {
// TODO(jgruber): Remove the intermediate ZoneHandleSet and then this function.
ZoneRefUnorderedSet<MapRef> ToRefSet(JSHeapBroker* broker,
const ZoneHandleSet<Map>& handles) {
ZoneRefUnorderedSet<MapRef> refs =
ZoneRefUnorderedSet<MapRef>(broker->zone());
for (Handle<Map> handle : handles) {
refs.insert(MakeRefAssumeMemoryFence(broker, *handle));
}
return refs;
}
ZoneRefUnorderedSet<MapRef> RefSetOf(JSHeapBroker* broker, const MapRef& ref) {
ZoneRefUnorderedSet<MapRef> refs =
ZoneRefUnorderedSet<MapRef>(broker->zone());
refs.insert(ref);
return refs;
}
} // namespace
// static
NodeProperties::InferMapsResult NodeProperties::InferMapsUnsafe(
JSHeapBroker* broker, Node* receiver, Node* effect,
ZoneHandleSet<Map>* maps_return) {
JSHeapBroker* broker, Node* receiver, Effect effect,
ZoneRefUnorderedSet<MapRef>* maps_out) {
HeapObjectMatcher m(receiver);
if (m.HasResolvedValue()) {
HeapObjectRef receiver = m.Ref(broker);
......@@ -364,7 +386,7 @@ NodeProperties::InferMapsResult NodeProperties::InferMapsUnsafe(
if (receiver.map().is_stable()) {
// The {receiver_map} is only reliable when we install a stability
// code dependency.
*maps_return = ZoneHandleSet<Map>(receiver.map().object());
*maps_out = RefSetOf(broker, receiver.map());
return kUnreliableMaps;
}
}
......@@ -375,7 +397,7 @@ NodeProperties::InferMapsResult NodeProperties::InferMapsUnsafe(
case IrOpcode::kMapGuard: {
Node* const object = GetValueInput(effect, 0);
if (IsSame(receiver, object)) {
*maps_return = MapGuardMapsOf(effect->op());
*maps_out = ToRefSet(broker, MapGuardMapsOf(effect->op()));
return result;
}
break;
......@@ -383,7 +405,8 @@ NodeProperties::InferMapsResult NodeProperties::InferMapsUnsafe(
case IrOpcode::kCheckMaps: {
Node* const object = GetValueInput(effect, 0);
if (IsSame(receiver, object)) {
*maps_return = CheckMapsParametersOf(effect->op()).maps();
*maps_out =
ToRefSet(broker, CheckMapsParametersOf(effect->op()).maps());
return result;
}
break;
......@@ -392,7 +415,7 @@ NodeProperties::InferMapsResult NodeProperties::InferMapsUnsafe(
if (IsSame(receiver, effect)) {
base::Optional<MapRef> initial_map = GetJSCreateMap(broker, receiver);
if (initial_map.has_value()) {
*maps_return = ZoneHandleSet<Map>(initial_map->object());
*maps_out = RefSetOf(broker, initial_map.value());
return result;
}
// We reached the allocation of the {receiver}.
......@@ -403,11 +426,10 @@ NodeProperties::InferMapsResult NodeProperties::InferMapsUnsafe(
}
case IrOpcode::kJSCreatePromise: {
if (IsSame(receiver, effect)) {
*maps_return =
ZoneHandleSet<Map>(broker->target_native_context()
.promise_function()
.initial_map(broker->dependencies())
.object());
*maps_out = RefSetOf(
broker,
broker->target_native_context().promise_function().initial_map(
broker->dependencies()));
return result;
}
break;
......@@ -422,7 +444,7 @@ NodeProperties::InferMapsResult NodeProperties::InferMapsUnsafe(
Node* const value = GetValueInput(effect, 1);
HeapObjectMatcher m(value);
if (m.HasResolvedValue()) {
*maps_return = ZoneHandleSet<Map>(m.Ref(broker).AsMap().object());
*maps_out = RefSetOf(broker, m.Ref(broker).AsMap());
return result;
}
}
......@@ -501,7 +523,7 @@ bool NodeProperties::NoObservableSideEffectBetween(Node* effect,
// static
bool NodeProperties::CanBePrimitive(JSHeapBroker* broker, Node* receiver,
Node* effect) {
Effect effect) {
switch (receiver->opcode()) {
#define CASE(Opcode) case IrOpcode::k##Opcode:
JS_CONSTRUCT_OP_LIST(CASE)
......@@ -526,7 +548,7 @@ bool NodeProperties::CanBePrimitive(JSHeapBroker* broker, Node* receiver,
// static
bool NodeProperties::CanBeNullOrUndefined(JSHeapBroker* broker, Node* receiver,
Node* effect) {
Effect effect) {
if (CanBePrimitive(broker, receiver, effect)) {
switch (receiver->opcode()) {
case IrOpcode::kCheckInternalizedString:
......
......@@ -6,6 +6,7 @@
#define V8_COMPILER_NODE_PROPERTIES_H_
#include "src/common/globals.h"
#include "src/compiler/heap-refs.h"
#include "src/compiler/node.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/types.h"
......@@ -219,9 +220,9 @@ class V8_EXPORT_PRIVATE NodeProperties {
kUnreliableMaps // Maps might have changed (side-effect).
};
// DO NOT USE InferMapsUnsafe IN NEW CODE. Use MapInference instead.
static InferMapsResult InferMapsUnsafe(JSHeapBroker* broker, Node* object,
Node* effect,
ZoneHandleSet<Map>* maps);
static InferMapsResult InferMapsUnsafe(JSHeapBroker* broker, Node* receiver,
Effect effect,
ZoneRefUnorderedSet<MapRef>* maps_out);
// Return the initial map of the new-target if the allocation can be inlined.
static base::Optional<MapRef> GetJSCreateMap(JSHeapBroker* broker,
......@@ -236,12 +237,12 @@ class V8_EXPORT_PRIVATE NodeProperties {
// definitely a JavaScript object); might walk up the {effect} chain to
// find map checks on {receiver}.
static bool CanBePrimitive(JSHeapBroker* broker, Node* receiver,
Node* effect);
Effect effect);
// Returns true if the {receiver} can be null or undefined. Might walk
// up the {effect} chain to find map checks for {receiver}.
static bool CanBeNullOrUndefined(JSHeapBroker* broker, Node* receiver,
Node* effect);
Effect effect);
// ---------------------------------------------------------------------------
// Context.
......
......@@ -153,7 +153,7 @@ class ElementAccessFeedback : public ProcessedFeedback {
// [e0, e1] [e0, e1]
//
ElementAccessFeedback const& Refine(
ZoneVector<Handle<Map>> const& inferred_maps, Zone* zone) const;
JSHeapBroker* broker, ZoneVector<MapRef> const& inferred_maps) const;
private:
KeyedAccessMode const keyed_mode_;
......
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