Unify implementations of Map handles vectors and lists

This CL introduces a new type, MapHandles, which is a STL vector of Handle<Map>.
It is now used everywhere where lists of Handle<Maps> are required, replacing
usages of V8's internal List type.

Also-By: franzih@chromium.org
BUG=v8:6333,v8:6325
LOG=N

Review-Url: https://codereview.chromium.org/2809923002
Cr-Commit-Position: refs/heads/master@{#45211}
This commit is contained in:
danno 2017-05-09 15:36:00 -07:00 committed by Commit bot
parent a459f188fa
commit fc274fbe99
15 changed files with 210 additions and 210 deletions

View File

@ -232,7 +232,7 @@ void CompilationJob::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
// TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
Isolate* const isolate = code->GetIsolate();
DCHECK(code->is_optimized_code());
std::vector<Handle<Map>> maps;
MapHandles maps;
std::vector<Handle<HeapObject>> objects;
{
DisallowHeapAllocation no_gc;

View File

@ -61,26 +61,26 @@ std::ostream& operator<<(std::ostream& os, AccessMode access_mode) {
ElementAccessInfo::ElementAccessInfo() {}
ElementAccessInfo::ElementAccessInfo(MapList const& receiver_maps,
ElementAccessInfo::ElementAccessInfo(MapHandles const& receiver_maps,
ElementsKind elements_kind)
: elements_kind_(elements_kind), receiver_maps_(receiver_maps) {}
// static
PropertyAccessInfo PropertyAccessInfo::NotFound(MapList const& receiver_maps,
PropertyAccessInfo PropertyAccessInfo::NotFound(MapHandles const& receiver_maps,
MaybeHandle<JSObject> holder) {
return PropertyAccessInfo(holder, receiver_maps);
}
// static
PropertyAccessInfo PropertyAccessInfo::DataConstant(
MapList const& receiver_maps, Handle<Object> constant,
MapHandles const& receiver_maps, Handle<Object> constant,
MaybeHandle<JSObject> holder) {
return PropertyAccessInfo(kDataConstant, holder, constant, receiver_maps);
}
// static
PropertyAccessInfo PropertyAccessInfo::DataField(
PropertyConstness constness, MapList const& receiver_maps,
PropertyConstness constness, MapHandles const& receiver_maps,
FieldIndex field_index, MachineRepresentation field_representation,
Type* field_type, MaybeHandle<Map> field_map, MaybeHandle<JSObject> holder,
MaybeHandle<Map> transition_map) {
@ -92,7 +92,7 @@ PropertyAccessInfo PropertyAccessInfo::DataField(
// static
PropertyAccessInfo PropertyAccessInfo::AccessorConstant(
MapList const& receiver_maps, Handle<Object> constant,
MapHandles const& receiver_maps, Handle<Object> constant,
MaybeHandle<JSObject> holder) {
return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps);
}
@ -103,7 +103,7 @@ PropertyAccessInfo::PropertyAccessInfo()
field_type_(Type::None()) {}
PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
MapList const& receiver_maps)
MapHandles const& receiver_maps)
: kind_(kNotFound),
receiver_maps_(receiver_maps),
holder_(holder),
@ -112,7 +112,7 @@ PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
Handle<Object> constant,
MapList const& receiver_maps)
MapHandles const& receiver_maps)
: kind_(kind),
receiver_maps_(receiver_maps),
constant_(constant),
@ -123,7 +123,8 @@ PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
PropertyAccessInfo::PropertyAccessInfo(
Kind kind, MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map,
FieldIndex field_index, MachineRepresentation field_representation,
Type* field_type, MaybeHandle<Map> field_map, MapList const& receiver_maps)
Type* field_type, MaybeHandle<Map> field_map,
MapHandles const& receiver_maps)
: kind_(kind),
receiver_maps_(receiver_maps),
transition_map_(transition_map),
@ -228,12 +229,12 @@ bool AccessInfoFactory::ComputeElementAccessInfo(
// Check if it is safe to inline element access for the {map}.
if (!CanInlineElementAccess(map)) return false;
ElementsKind const elements_kind = map->elements_kind();
*access_info = ElementAccessInfo(MapList{map}, elements_kind);
*access_info = ElementAccessInfo(MapHandles{map}, elements_kind);
return true;
}
bool AccessInfoFactory::ComputeElementAccessInfos(
MapHandleList const& maps, AccessMode access_mode,
MapHandles const& maps, AccessMode access_mode,
ZoneVector<ElementAccessInfo>* access_infos) {
if (access_mode == AccessMode::kLoad) {
// For polymorphic loads of similar elements kinds (i.e. all tagged or all
@ -248,26 +249,28 @@ bool AccessInfoFactory::ComputeElementAccessInfos(
}
// Collect possible transition targets.
MapHandleList possible_transition_targets(maps.length());
MapHandles possible_transition_targets;
possible_transition_targets.reserve(maps.size());
for (Handle<Map> map : maps) {
if (Map::TryUpdate(map).ToHandle(&map)) {
if (CanInlineElementAccess(map) &&
IsFastElementsKind(map->elements_kind()) &&
GetInitialFastElementsKind() != map->elements_kind()) {
possible_transition_targets.Add(map);
possible_transition_targets.push_back(map);
}
}
}
// Separate the actual receiver maps and the possible transition sources.
MapHandleList receiver_maps(maps.length());
MapTransitionList transitions(maps.length());
MapHandles receiver_maps;
receiver_maps.reserve(maps.size());
MapTransitionList transitions(maps.size());
for (Handle<Map> map : maps) {
if (Map::TryUpdate(map).ToHandle(&map)) {
Map* transition_target =
map->FindElementsKindTransitionedMap(&possible_transition_targets);
map->FindElementsKindTransitionedMap(possible_transition_targets);
if (transition_target == nullptr) {
receiver_maps.Add(map);
receiver_maps.push_back(map);
} else {
DCHECK(!map->is_stable());
transitions.push_back(std::make_pair(map, handle(transition_target)));
@ -375,7 +378,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
}
}
*access_info = PropertyAccessInfo::DataField(
details.constness(), MapList{receiver_map}, field_index,
details.constness(), MapHandles{receiver_map}, field_index,
field_representation, field_type, field_map, holder);
return true;
} else {
@ -389,7 +392,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
if (details.kind() == kData) {
DCHECK(!FLAG_track_constant_fields);
*access_info = PropertyAccessInfo::DataConstant(
MapList{receiver_map},
MapHandles{receiver_map},
handle(descriptors->GetValue(number), isolate()), holder);
return true;
} else {
@ -420,7 +423,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
}
}
*access_info = PropertyAccessInfo::AccessorConstant(
MapList{receiver_map}, accessor, holder);
MapHandles{receiver_map}, accessor, holder);
return true;
}
}
@ -463,7 +466,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
// on the language mode of the load operation.
// Implemented according to ES6 section 9.1.8 [[Get]] (P, Receiver)
*access_info =
PropertyAccessInfo::NotFound(MapList{receiver_map}, holder);
PropertyAccessInfo::NotFound(MapHandles{receiver_map}, holder);
return true;
} else {
return false;
@ -482,7 +485,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
}
bool AccessInfoFactory::ComputePropertyAccessInfos(
MapHandleList const& maps, Handle<Name> name, AccessMode access_mode,
MapHandles const& maps, Handle<Name> name, AccessMode access_mode,
ZoneVector<PropertyAccessInfo>* access_infos) {
for (Handle<Map> map : maps) {
if (Map::TryUpdate(map).ToHandle(&map)) {
@ -528,14 +531,12 @@ Maybe<ElementsKind> GeneralizeElementsKind(ElementsKind this_kind,
} // namespace
bool AccessInfoFactory::ConsolidateElementLoad(MapHandleList const& maps,
bool AccessInfoFactory::ConsolidateElementLoad(MapHandles const& maps,
ElementAccessInfo* access_info) {
if (maps.is_empty()) return false;
InstanceType instance_type = maps.first()->instance_type();
ElementsKind elements_kind = maps.first()->elements_kind();
MapList receiver_maps(maps.length());
for (int i = 0; i < maps.length(); ++i) {
Handle<Map> map = maps[i];
if (maps.empty()) return false;
InstanceType instance_type = maps.front()->instance_type();
ElementsKind elements_kind = maps.front()->elements_kind();
for (Handle<Map> map : maps) {
if (!CanInlineElementAccess(map) || map->instance_type() != instance_type) {
return false;
}
@ -543,9 +544,8 @@ bool AccessInfoFactory::ConsolidateElementLoad(MapHandleList const& maps,
.To(&elements_kind)) {
return false;
}
receiver_maps[i] = map;
}
*access_info = ElementAccessInfo(receiver_maps, elements_kind);
*access_info = ElementAccessInfo(maps, elements_kind);
return true;
}
@ -581,8 +581,9 @@ bool AccessInfoFactory::LookupSpecialFieldAccessor(
}
}
// Special fields are always mutable.
*access_info = PropertyAccessInfo::DataField(
kMutable, MapList{map}, field_index, field_representation, field_type);
*access_info =
PropertyAccessInfo::DataField(kMutable, MapHandles{map}, field_index,
field_representation, field_type);
return true;
}
return false;
@ -640,8 +641,8 @@ bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
dependencies()->AssumeMapNotDeprecated(transition_map);
// Transitioning stores are never stores to constant fields.
*access_info = PropertyAccessInfo::DataField(
kMutable, MapList{map}, field_index, field_representation, field_type,
field_map, holder, transition_map);
kMutable, MapHandles{map}, field_index, field_representation,
field_type, field_map, holder, transition_map);
return true;
}
return false;

View File

@ -31,8 +31,6 @@ enum class AccessMode { kLoad, kStore, kStoreInLiteral };
std::ostream& operator<<(std::ostream&, AccessMode);
typedef std::vector<Handle<Map>> MapList;
// Mapping of transition source to transition target.
typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
@ -40,16 +38,17 @@ typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
class ElementAccessInfo final {
public:
ElementAccessInfo();
ElementAccessInfo(MapList const& receiver_maps, ElementsKind elements_kind);
ElementAccessInfo(MapHandles const& receiver_maps,
ElementsKind elements_kind);
ElementsKind elements_kind() const { return elements_kind_; }
MapList const& receiver_maps() const { return receiver_maps_; }
MapHandles const& receiver_maps() const { return receiver_maps_; }
MapTransitionList& transitions() { return transitions_; }
MapTransitionList const& transitions() const { return transitions_; }
private:
ElementsKind elements_kind_;
MapList receiver_maps_;
MapHandles receiver_maps_;
MapTransitionList transitions_;
};
@ -66,18 +65,18 @@ class PropertyAccessInfo final {
kAccessorConstant
};
static PropertyAccessInfo NotFound(MapList const& receiver_maps,
static PropertyAccessInfo NotFound(MapHandles const& receiver_maps,
MaybeHandle<JSObject> holder);
static PropertyAccessInfo DataConstant(MapList const& receiver_maps,
static PropertyAccessInfo DataConstant(MapHandles const& receiver_maps,
Handle<Object> constant,
MaybeHandle<JSObject> holder);
static PropertyAccessInfo DataField(
PropertyConstness constness, MapList const& receiver_maps,
PropertyConstness constness, MapHandles const& receiver_maps,
FieldIndex field_index, MachineRepresentation field_representation,
Type* field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(),
MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
MaybeHandle<Map> transition_map = MaybeHandle<Map>());
static PropertyAccessInfo AccessorConstant(MapList const& receiver_maps,
static PropertyAccessInfo AccessorConstant(MapHandles const& receiver_maps,
Handle<Object> constant,
MaybeHandle<JSObject> holder);
@ -106,21 +105,21 @@ class PropertyAccessInfo final {
return field_representation_;
}
MaybeHandle<Map> field_map() const { return field_map_; }
MapList const& receiver_maps() const { return receiver_maps_; }
MapHandles const& receiver_maps() const { return receiver_maps_; }
private:
PropertyAccessInfo(MaybeHandle<JSObject> holder,
MapList const& receiver_maps);
MapHandles const& receiver_maps);
PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
Handle<Object> constant, MapList const& receiver_maps);
Handle<Object> constant, MapHandles const& receiver_maps);
PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
MaybeHandle<Map> transition_map, FieldIndex field_index,
MachineRepresentation field_representation,
Type* field_type, MaybeHandle<Map> field_map,
MapList const& receiver_maps);
MapHandles const& receiver_maps);
Kind kind_;
MapList receiver_maps_;
MapHandles receiver_maps_;
Handle<Object> constant_;
MaybeHandle<Map> transition_map_;
MaybeHandle<JSObject> holder_;
@ -139,18 +138,17 @@ class AccessInfoFactory final {
bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
ElementAccessInfo* access_info);
bool ComputeElementAccessInfos(MapHandleList const& maps,
AccessMode access_mode,
bool ComputeElementAccessInfos(MapHandles const& maps, AccessMode access_mode,
ZoneVector<ElementAccessInfo>* access_infos);
bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
AccessMode access_mode,
PropertyAccessInfo* access_info);
bool ComputePropertyAccessInfos(MapHandleList const& maps, Handle<Name> name,
bool ComputePropertyAccessInfos(MapHandles const& maps, Handle<Name> name,
AccessMode access_mode,
ZoneVector<PropertyAccessInfo>* access_infos);
private:
bool ConsolidateElementLoad(MapHandleList const& maps,
bool ConsolidateElementLoad(MapHandles const& maps,
ElementAccessInfo* access_info);
bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
PropertyAccessInfo* access_info);

View File

@ -24,21 +24,21 @@ namespace compiler {
namespace {
bool HasNumberMaps(MapList const& maps) {
bool HasNumberMaps(MapHandles const& maps) {
for (auto map : maps) {
if (map->instance_type() == HEAP_NUMBER_TYPE) return true;
}
return false;
}
bool HasOnlyJSArrayMaps(MapList const& maps) {
bool HasOnlyJSArrayMaps(MapHandles const& maps) {
for (auto map : maps) {
if (!map->IsJSArrayMap()) return false;
}
return true;
}
bool HasOnlyNumberMaps(MapList const& maps) {
bool HasOnlyNumberMaps(MapHandles const& maps) {
for (auto map : maps) {
if (map->instance_type() != HEAP_NUMBER_TYPE) return false;
}
@ -706,9 +706,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) {
}
Reduction JSNativeContextSpecialization::ReduceNamedAccess(
Node* node, Node* value, MapHandleList const& receiver_maps,
Handle<Name> name, AccessMode access_mode, LanguageMode language_mode,
Node* index) {
Node* node, Node* value, MapHandles const& receiver_maps, Handle<Name> name,
AccessMode access_mode, LanguageMode language_mode, Node* index) {
DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
node->opcode() == IrOpcode::kJSStoreNamed ||
node->opcode() == IrOpcode::kJSLoadProperty ||
@ -723,8 +722,8 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
// Check if we have an access o.x or o.x=v where o is the current
// native contexts' global proxy, and turn that into a direct access
// to the current native contexts' global object instead.
if (receiver_maps.length() == 1) {
Handle<Map> receiver_map = receiver_maps.first();
if (receiver_maps.size() == 1) {
Handle<Map> receiver_map = receiver_maps.front();
if (receiver_map->IsJSGlobalProxyMap()) {
Object* maybe_constructor = receiver_map->GetConstructor();
// Detached global proxies have |null| as their constructor.
@ -841,7 +840,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
Node* this_control = fallthrough_control;
// Perform map check on {receiver}.
MapList const& receiver_maps = access_info.receiver_maps();
MapHandles const& receiver_maps = access_info.receiver_maps();
{
// Emit a (sequence of) map checks for other {receiver}s.
ZoneVector<Node*> this_controls(zone());
@ -956,10 +955,10 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus(
}
// Extract receiver maps from the IC using the {nexus}.
MapHandleList receiver_maps;
MapHandles receiver_maps;
if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
return NoChange();
} else if (receiver_maps.length() == 0) {
} else if (receiver_maps.empty()) {
if (flags() & kBailoutOnUninitialized) {
return ReduceSoftDeoptimize(
node,
@ -1047,7 +1046,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) {
}
Reduction JSNativeContextSpecialization::ReduceElementAccess(
Node* node, Node* index, Node* value, MapHandleList const& receiver_maps,
Node* node, Node* index, Node* value, MapHandles const& receiver_maps,
AccessMode access_mode, LanguageMode language_mode,
KeyedAccessStoreMode store_mode) {
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
@ -1211,7 +1210,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
receiver, this_effect, this_control);
// Perform map check(s) on {receiver}.
MapList const& receiver_maps = access_info.receiver_maps();
MapHandles const& receiver_maps = access_info.receiver_maps();
if (j == access_infos.size() - 1) {
// Last map check on the fallthrough control path, do a
// conditional eager deoptimization exit here.
@ -1344,10 +1343,10 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
}
// Extract receiver maps from the {nexus}.
MapHandleList receiver_maps;
MapHandles receiver_maps;
if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
return NoChange();
} else if (receiver_maps.length() == 0) {
} else if (receiver_maps.empty()) {
if (flags() & kBailoutOnUninitialized) {
return ReduceSoftDeoptimize(
node,
@ -1911,7 +1910,7 @@ JSNativeContextSpecialization::BuildElementAccess(
// TODO(bmeurer): We currently specialize based on elements kind. We should
// also be able to properly support strings and other JSObjects here.
ElementsKind elements_kind = access_info.elements_kind();
MapList const& receiver_maps = access_info.receiver_maps();
MapHandles const& receiver_maps = access_info.receiver_maps();
if (IsFixedTypedArrayElementsKind(elements_kind)) {
Node* buffer;
@ -2282,7 +2281,7 @@ Node* JSNativeContextSpecialization::BuildCheckHeapObject(Node* receiver,
Node* JSNativeContextSpecialization::BuildCheckMaps(
Node* receiver, Node* effect, Node* control,
std::vector<Handle<Map>> const& receiver_maps) {
MapHandles const& receiver_maps) {
HeapObjectMatcher m(receiver);
if (m.HasValue()) {
Handle<Map> receiver_map(m.Value()->map(), isolate());
@ -2356,7 +2355,7 @@ Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore(
}
void JSNativeContextSpecialization::AssumePrototypesStable(
std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) {
MapHandles const& receiver_maps, Handle<JSObject> holder) {
// Determine actual holder and perform prototype chain checks.
for (auto map : receiver_maps) {
// Perform the implicit ToObject for primitives here.
@ -2371,7 +2370,7 @@ void JSNativeContextSpecialization::AssumePrototypesStable(
}
bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
std::vector<Handle<Map>> const& receiver_maps) {
MapHandles const& receiver_maps) {
// Check if the array prototype chain is intact.
if (!isolate()->IsFastArrayConstructorPrototypeChainIntact()) return false;
@ -2458,8 +2457,8 @@ JSNativeContextSpecialization::InferHasInPrototypeChain(
bool JSNativeContextSpecialization::ExtractReceiverMaps(
Node* receiver, Node* effect, FeedbackNexus const& nexus,
MapHandleList* receiver_maps) {
DCHECK_EQ(0, receiver_maps->length());
MapHandles* receiver_maps) {
DCHECK_EQ(0, receiver_maps->size());
// See if we can infer a concrete type for the {receiver}.
if (InferReceiverMaps(receiver, effect, receiver_maps)) {
// We can assume that the {receiver} still has the infered {receiver_maps}.
@ -2470,11 +2469,12 @@ bool JSNativeContextSpecialization::ExtractReceiverMaps(
// Try to filter impossible candidates based on infered root map.
Handle<Map> receiver_map;
if (InferReceiverRootMap(receiver).ToHandle(&receiver_map)) {
for (int i = receiver_maps->length(); --i >= 0;) {
if (receiver_maps->at(i)->FindRootMap() != *receiver_map) {
receiver_maps->Remove(i);
}
}
receiver_maps->erase(
std::remove_if(receiver_maps->begin(), receiver_maps->end(),
[receiver_map](const Handle<Map>& map) {
return map->FindRootMap() != *receiver_map;
}),
receiver_maps->end());
}
return true;
}
@ -2482,13 +2482,13 @@ bool JSNativeContextSpecialization::ExtractReceiverMaps(
}
bool JSNativeContextSpecialization::InferReceiverMaps(
Node* receiver, Node* effect, MapHandleList* receiver_maps) {
Node* receiver, Node* effect, MapHandles* receiver_maps) {
ZoneHandleSet<Map> maps;
NodeProperties::InferReceiverMapsResult result =
NodeProperties::InferReceiverMaps(receiver, effect, &maps);
if (result == NodeProperties::kReliableReceiverMaps) {
for (size_t i = 0; i < maps.size(); ++i) {
receiver_maps->Add(maps[i]);
receiver_maps->push_back(maps[i]);
}
return true;
} else if (result == NodeProperties::kUnreliableReceiverMaps) {
@ -2498,7 +2498,7 @@ bool JSNativeContextSpecialization::InferReceiverMaps(
if (!maps[i]->is_stable()) return false;
}
for (size_t i = 0; i < maps.size(); ++i) {
receiver_maps->Add(maps[i]);
receiver_maps->push_back(maps[i]);
}
return true;
}

View File

@ -67,7 +67,7 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
Reduction ReduceJSStoreDataPropertyInLiteral(Node* node);
Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
MapHandleList const& receiver_maps,
MapHandles const& receiver_maps,
AccessMode access_mode,
LanguageMode language_mode,
KeyedAccessStoreMode store_mode);
@ -82,7 +82,7 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
AccessMode access_mode,
LanguageMode language_mode);
Reduction ReduceNamedAccess(Node* node, Node* value,
MapHandleList const& receiver_maps,
MapHandles const& receiver_maps,
Handle<Name> name, AccessMode access_mode,
LanguageMode language_mode,
Node* index = nullptr);
@ -130,7 +130,7 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
// Construct an appropriate map check.
Node* BuildCheckMaps(Node* receiver, Node* effect, Node* control,
std::vector<Handle<Map>> const& maps);
MapHandles const& maps);
// Construct appropriate subgraph to extend properties backing store.
Node* BuildExtendPropertiesBackingStore(Handle<Map> map, Node* properties,
@ -138,13 +138,13 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
// Adds stability dependencies on all prototypes of every class in
// {receiver_type} up to (and including) the {holder}.
void AssumePrototypesStable(std::vector<Handle<Map>> const& receiver_maps,
void AssumePrototypesStable(MapHandles const& receiver_maps,
Handle<JSObject> holder);
// Checks if we can turn the hole into undefined when loading an element
// from an object with one of the {receiver_maps}; sets up appropriate
// code dependencies and might use the array protector cell.
bool CanTreatHoleAsUndefined(std::vector<Handle<Map>> const& receiver_maps);
bool CanTreatHoleAsUndefined(MapHandles const& receiver_maps);
// Checks if we know at compile time that the {receiver} either definitely
// has the {prototype} in it's prototype chain, or the {receiver} definitely
@ -161,14 +161,14 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
// possible.
bool ExtractReceiverMaps(Node* receiver, Node* effect,
FeedbackNexus const& nexus,
MapHandleList* receiver_maps);
MapHandles* receiver_maps);
// Try to infer maps for the given {receiver} at the current {effect}.
// If maps are returned then you can be sure that the {receiver} definitely
// has one of the returned maps at this point in the program (identified
// by {effect}).
bool InferReceiverMaps(Node* receiver, Node* effect,
MapHandleList* receiver_maps);
MapHandles* receiver_maps);
// Try to infer a root map for the {receiver} independent of the current
// program location.
MaybeHandle<Map> InferReceiverRootMap(Node* receiver);

View File

@ -6914,9 +6914,11 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
}
// Elements_kind transition support.
MapHandleList transition_target(maps->length());
MapHandles transition_target;
transition_target.reserve(maps->length());
// Collect possible transition targets.
MapHandleList possible_transitioned_maps(maps->length());
MapHandles possible_transitioned_maps;
possible_transitioned_maps.reserve(maps->length());
for (int i = 0; i < maps->length(); ++i) {
Handle<Map> map = maps->at(i);
// Loads from strings or loads with a mix of string and non-string maps
@ -6925,7 +6927,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
ElementsKind elements_kind = map->elements_kind();
if (CanInlineElementAccess(map) && IsFastElementsKind(elements_kind) &&
elements_kind != GetInitialFastElementsKind()) {
possible_transitioned_maps.Add(map);
possible_transitioned_maps.push_back(map);
}
if (IsSloppyArgumentsElementsKind(elements_kind)) {
HInstruction* result =
@ -6938,16 +6940,17 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
for (int i = 0; i < maps->length(); ++i) {
Handle<Map> map = maps->at(i);
Map* transitioned_map =
map->FindElementsKindTransitionedMap(&possible_transitioned_maps);
map->FindElementsKindTransitionedMap(possible_transitioned_maps);
if (transitioned_map != nullptr) {
DCHECK(!map->is_stable());
transition_target.Add(handle(transitioned_map));
transition_target.push_back(handle(transitioned_map));
} else {
transition_target.Add(Handle<Map>());
transition_target.push_back(Handle<Map>());
}
}
MapHandleList untransitionable_maps(maps->length());
MapHandles untransitionable_maps;
untransitionable_maps.reserve(maps->length());
HTransitionElementsKind* transition = NULL;
for (int i = 0; i < maps->length(); ++i) {
Handle<Map> map = maps->at(i);
@ -6959,14 +6962,14 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
transition = Add<HTransitionElementsKind>(object, map,
transition_target.at(i));
} else {
untransitionable_maps.Add(map);
untransitionable_maps.push_back(map);
}
}
// If only one map is left after transitioning, handle this case
// monomorphically.
DCHECK(untransitionable_maps.length() >= 1);
if (untransitionable_maps.length() == 1) {
DCHECK(untransitionable_maps.size() >= 1);
if (untransitionable_maps.size() == 1) {
Handle<Map> untransitionable_map = untransitionable_maps[0];
HInstruction* instr = NULL;
if (!CanInlineElementAccess(untransitionable_map)) {
@ -6983,8 +6986,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
HBasicBlock* join = graph()->CreateBasicBlock();
for (int i = 0; i < untransitionable_maps.length(); ++i) {
Handle<Map> map = untransitionable_maps[i];
for (Handle<Map> map : untransitionable_maps) {
ElementsKind elements_kind = map->elements_kind();
HBasicBlock* this_map = graph()->CreateBasicBlock();
HBasicBlock* other_map = graph()->CreateBasicBlock();

View File

@ -646,9 +646,10 @@ void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
}
}
void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
MapHandles const& maps,
List<Handle<Object>>* handlers) {
int receiver_count = maps->length();
int receiver_count = static_cast<int>(maps.size());
DCHECK(receiver_count > 1);
Handle<FixedArray> array;
if (name.is_null()) {
@ -661,14 +662,14 @@ void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
}
for (int current = 0; current < receiver_count; ++current) {
Handle<Map> map = maps->at(current);
Handle<Map> map = maps[current];
Handle<WeakCell> cell = Map::WeakCellForMap(map);
array->set(current * 2, *cell);
array->set(current * 2 + 1, *handlers->at(current));
}
}
int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
bool is_named_feedback = IsPropertyNameFeedback(feedback);
@ -684,7 +685,7 @@ int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
WeakCell* cell = WeakCell::cast(array->get(i));
if (!cell->cleared()) {
Map* map = Map::cast(cell->value());
maps->Add(handle(map, isolate));
maps->push_back(handle(map, isolate));
found++;
}
}
@ -693,7 +694,7 @@ int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
WeakCell* cell = WeakCell::cast(feedback);
if (!cell->cleared()) {
Map* map = Map::cast(cell->value());
maps->Add(handle(map, isolate));
maps->push_back(handle(map, isolate));
return 1;
}
}
@ -791,13 +792,13 @@ Name* KeyedStoreICNexus::FindFirstName() const {
KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const {
KeyedAccessStoreMode mode = STANDARD_STORE;
MapHandleList maps;
MapHandles maps;
List<Handle<Object>> handlers;
if (GetKeyType() == PROPERTY) return mode;
ExtractMaps(&maps);
FindHandlers(&handlers, maps.length());
FindHandlers(&handlers, static_cast<int>(maps.size()));
for (int i = 0; i < handlers.length(); i++) {
// The first handler that isn't the slow handler will have the bits we need.
Handle<Object> maybe_code_handler = handlers.at(i);

View File

@ -477,14 +477,14 @@ class FeedbackNexus {
InlineCacheState ic_state() const { return StateFromFeedback(); }
bool IsUninitialized() const { return StateFromFeedback() == UNINITIALIZED; }
Map* FindFirstMap() const {
MapHandleList maps;
MapHandles maps;
ExtractMaps(&maps);
if (maps.length() > 0) return *maps.at(0);
if (maps.size() > 0) return *maps.at(0);
return NULL;
}
virtual InlineCacheState StateFromFeedback() const = 0;
virtual int ExtractMaps(MapHandleList* maps) const;
virtual int ExtractMaps(MapHandles* maps) const;
virtual MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const;
virtual bool FindHandlers(List<Handle<Object>>* code_list,
int length = -1) const;
@ -508,7 +508,7 @@ class FeedbackNexus {
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Handle<Object> handler);
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
void ConfigurePolymorphic(Handle<Name> name, MapHandles const& maps,
List<Handle<Object>>* handlers);
protected:
@ -545,7 +545,7 @@ class CallICNexus final : public FeedbackNexus {
InlineCacheState StateFromFeedback() const final;
int ExtractMaps(MapHandleList* maps) const final {
int ExtractMaps(MapHandles* maps) const final {
// CallICs don't record map feedback.
return 0;
}
@ -591,7 +591,7 @@ class LoadGlobalICNexus : public FeedbackNexus {
DCHECK(vector->IsLoadGlobalIC(slot));
}
int ExtractMaps(MapHandleList* maps) const final {
int ExtractMaps(MapHandles* maps) const final {
// LoadGlobalICs don't record map feedback.
return 0;
}
@ -684,7 +684,7 @@ class BinaryOpICNexus final : public FeedbackNexus {
InlineCacheState StateFromFeedback() const final;
BinaryOperationHint GetBinaryOperationFeedback() const;
int ExtractMaps(MapHandleList* maps) const final {
int ExtractMaps(MapHandles* maps) const final {
// BinaryOpICs don't record map feedback.
return 0;
}
@ -711,7 +711,7 @@ class CompareICNexus final : public FeedbackNexus {
InlineCacheState StateFromFeedback() const final;
CompareOperationHint GetCompareOperationFeedback() const;
int ExtractMaps(MapHandleList* maps) const final {
int ExtractMaps(MapHandles* maps) const final {
// BinaryOpICs don't record map feedback.
return 0;
}

View File

@ -549,7 +549,7 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
OnFeedbackChanged(isolate(), GetHostFunction());
}
void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
void IC::ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
List<Handle<Object>>* handlers) {
DCHECK(!IsLoadGlobalIC());
// Non-keyed ICs don't track the name explicitly.
@ -636,16 +636,15 @@ MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) {
return LoadIC::Load(global, name);
}
static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
static bool AddOneReceiverMapIfMissing(MapHandles* receiver_maps,
Handle<Map> new_receiver_map) {
DCHECK(!new_receiver_map.is_null());
for (int current = 0; current < receiver_maps->length(); ++current) {
if (!receiver_maps->at(current).is_null() &&
receiver_maps->at(current).is_identical_to(new_receiver_map)) {
for (Handle<Map> map : *receiver_maps) {
if (!map.is_null() && map.is_identical_to(new_receiver_map)) {
return false;
}
}
receiver_maps->Add(new_receiver_map);
receiver_maps->push_back(new_receiver_map);
return true;
}
@ -653,11 +652,11 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Object> handler) {
DCHECK(IsHandler(*handler));
if (is_keyed() && state() != RECOMPUTE_HANDLER) return false;
Handle<Map> map = receiver_map();
MapHandleList maps;
MapHandles maps;
List<Handle<Object>> handlers;
TargetMaps(&maps);
int number_of_maps = maps.length();
int number_of_maps = static_cast<int>(maps.size());
int deprecated_maps = 0;
int handler_to_overwrite = -1;
@ -684,7 +683,9 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Object> handler) {
if (number_of_maps == 0 && state() != MONOMORPHIC && state() != POLYMORPHIC) {
return false;
}
if (!nexus()->FindHandlers(&handlers, maps.length())) return false;
if (!nexus()->FindHandlers(&handlers, static_cast<int>(maps.size()))) {
return false;
}
number_of_valid_maps++;
if (number_of_valid_maps > 1 && is_keyed()) return false;
@ -694,14 +695,14 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Object> handler) {
if (handler_to_overwrite >= 0) {
handlers.Set(handler_to_overwrite, handler);
if (!map.is_identical_to(maps.at(handler_to_overwrite))) {
maps.Set(handler_to_overwrite, map);
maps[handler_to_overwrite] = map;
}
} else {
maps.Add(map);
maps.push_back(map);
handlers.Add(handler);
}
ConfigureVectorState(name, &maps, &handlers);
ConfigureVectorState(name, maps, &handlers);
}
return true;
@ -714,11 +715,11 @@ void IC::UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name) {
void IC::CopyICToMegamorphicCache(Handle<Name> name) {
MapHandleList maps;
MapHandles maps;
List<Handle<Object>> handlers;
TargetMaps(&maps);
if (!nexus()->FindHandlers(&handlers, maps.length())) return;
for (int i = 0; i < maps.length(); i++) {
if (!nexus()->FindHandlers(&handlers, static_cast<int>(maps.size()))) return;
for (int i = 0; i < static_cast<int>(maps.size()); i++) {
UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i));
}
}
@ -732,9 +733,9 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
source_map->elements_kind(), target_elements_kind);
Map* transitioned_map = nullptr;
if (more_general_transition) {
MapHandleList map_list;
map_list.Add(handle(target_map));
transitioned_map = source_map->FindElementsKindTransitionedMap(&map_list);
MapHandles map_list;
map_list.push_back(handle(target_map));
transitioned_map = source_map->FindElementsKindTransitionedMap(map_list);
}
return transitioned_map == target_map;
}
@ -1323,16 +1324,15 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) {
Handle<Map> receiver_map(receiver->map(), isolate());
DCHECK(receiver_map->instance_type() != JS_VALUE_TYPE &&
receiver_map->instance_type() != JS_PROXY_TYPE); // Checked by caller.
MapHandleList target_receiver_maps;
MapHandles target_receiver_maps;
TargetMaps(&target_receiver_maps);
if (target_receiver_maps.length() == 0) {
if (target_receiver_maps.empty()) {
Handle<Object> handler = LoadElementHandler(receiver_map);
return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
}
for (int i = 0; i < target_receiver_maps.length(); i++) {
Handle<Map> map = target_receiver_maps.at(i);
for (Handle<Map> map : target_receiver_maps) {
if (map.is_null()) continue;
if (map->instance_type() == JS_VALUE_TYPE) {
TRACE_GENERIC_IC("JSValue");
@ -1372,19 +1372,19 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) {
// If the maximum number of receiver maps has been exceeded, use the generic
// version of the IC.
if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
if (target_receiver_maps.size() > kMaxKeyedPolymorphism) {
TRACE_GENERIC_IC("max polymorph exceeded");
return;
}
List<Handle<Object>> handlers(target_receiver_maps.length());
List<Handle<Object>> handlers(static_cast<int>(target_receiver_maps.size()));
LoadElementPolymorphicHandlers(&target_receiver_maps, &handlers);
DCHECK_LE(1, target_receiver_maps.length());
if (target_receiver_maps.length() == 1) {
ConfigureVectorState(Handle<Name>(), target_receiver_maps.at(0),
DCHECK_LE(1, target_receiver_maps.size());
if (target_receiver_maps.size() == 1) {
ConfigureVectorState(Handle<Name>(), target_receiver_maps[0],
handlers.at(0));
} else {
ConfigureVectorState(Handle<Name>(), &target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>(), target_receiver_maps, &handlers);
}
}
@ -1429,20 +1429,20 @@ Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map) {
}
void KeyedLoadIC::LoadElementPolymorphicHandlers(
MapHandleList* receiver_maps, List<Handle<Object>>* handlers) {
for (int i = 0; i < receiver_maps->length(); ++i) {
Handle<Map> receiver_map(receiver_maps->at(i));
if (receiver_map->is_deprecated()) {
// Filter out deprecated maps to ensure their instances get migrated.
receiver_maps->Remove(i--);
continue;
}
MapHandles* receiver_maps, List<Handle<Object>>* handlers) {
// Filter out deprecated maps to ensure their instances get migrated.
receiver_maps->erase(
std::remove_if(
receiver_maps->begin(), receiver_maps->end(),
[](const Handle<Map>& map) { return map->is_deprecated(); }),
receiver_maps->end());
for (Handle<Map> receiver_map : *receiver_maps) {
// Mark all stable receiver maps that have elements kind transition map
// among receiver_maps as unstable because the optimizing compilers may
// generate an elements kind transition for this kind of receivers.
if (receiver_map->is_stable()) {
Map* tmap = receiver_map->FindElementsKindTransitionedMap(receiver_maps);
Map* tmap = receiver_map->FindElementsKindTransitionedMap(*receiver_maps);
if (tmap != nullptr) {
receiver_map->NotifyLeafMapLayoutChange();
}
@ -1925,9 +1925,9 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup) {
void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode) {
MapHandleList target_receiver_maps;
MapHandles target_receiver_maps;
TargetMaps(&target_receiver_maps);
if (target_receiver_maps.length() == 0) {
if (target_receiver_maps.empty()) {
Handle<Map> monomorphic_map =
ComputeTransitionedMap(receiver_map, store_mode);
store_mode = GetNonTransitioningStoreMode(store_mode);
@ -1935,9 +1935,8 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler);
}
for (int i = 0; i < target_receiver_maps.length(); i++) {
if (!target_receiver_maps.at(i).is_null() &&
target_receiver_maps.at(i)->instance_type() == JS_VALUE_TYPE) {
for (Handle<Map> map : target_receiver_maps) {
if (!map.is_null() && map->instance_type() == JS_VALUE_TYPE) {
TRACE_GENERIC_IC("JSValue");
return;
}
@ -2002,7 +2001,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
// If the maximum number of receiver maps has been exceeded, use the
// megamorphic version of the IC.
if (target_receiver_maps.length() > kMaxKeyedPolymorphism) return;
if (target_receiver_maps.size() > kMaxKeyedPolymorphism) return;
// Make sure all polymorphic handlers have the same store mode, otherwise the
// megamorphic stub must be used.
@ -2020,27 +2019,27 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
// receivers are either external arrays, or all "normal" arrays. Otherwise,
// use the megamorphic stub.
if (store_mode != STANDARD_STORE) {
int external_arrays = 0;
for (int i = 0; i < target_receiver_maps.length(); ++i) {
if (target_receiver_maps[i]->has_fixed_typed_array_elements()) {
size_t external_arrays = 0;
for (Handle<Map> map : target_receiver_maps) {
if (map->has_fixed_typed_array_elements()) {
external_arrays++;
}
}
if (external_arrays != 0 &&
external_arrays != target_receiver_maps.length()) {
external_arrays != target_receiver_maps.size()) {
TRACE_GENERIC_IC("unsupported combination of external and normal arrays");
return;
}
}
List<Handle<Object>> handlers(target_receiver_maps.length());
List<Handle<Object>> handlers(static_cast<int>(target_receiver_maps.size()));
StoreElementPolymorphicHandlers(&target_receiver_maps, &handlers, store_mode);
DCHECK_LE(1, target_receiver_maps.length());
if (target_receiver_maps.length() == 1) {
ConfigureVectorState(Handle<Name>(), target_receiver_maps.at(0),
DCHECK_LE(1, target_receiver_maps.size());
if (target_receiver_maps.size() == 1) {
ConfigureVectorState(Handle<Name>(), target_receiver_maps[0],
handlers.at(0));
} else {
ConfigureVectorState(Handle<Name>(), &target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>(), target_receiver_maps, &handlers);
}
}
@ -2106,21 +2105,21 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
}
void KeyedStoreIC::StoreElementPolymorphicHandlers(
MapHandleList* receiver_maps, List<Handle<Object>>* handlers,
MapHandles* receiver_maps, List<Handle<Object>>* handlers,
KeyedAccessStoreMode store_mode) {
DCHECK(store_mode == STANDARD_STORE ||
store_mode == STORE_AND_GROW_NO_TRANSITION ||
store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
store_mode == STORE_NO_TRANSITION_HANDLE_COW);
for (int i = 0; i < receiver_maps->length(); ++i) {
Handle<Map> receiver_map(receiver_maps->at(i));
if (receiver_map->is_deprecated()) {
// Filter out deprecated maps to ensure their instances get migrated.
receiver_maps->Remove(i--);
continue;
}
// Filter out deprecated maps to ensure their instances get migrated.
receiver_maps->erase(
std::remove_if(
receiver_maps->begin(), receiver_maps->end(),
[](const Handle<Map>& map) { return map->is_deprecated(); }),
receiver_maps->end());
for (Handle<Map> receiver_map : *receiver_maps) {
Handle<Object> handler;
Handle<Map> transitioned_map;
@ -2134,7 +2133,7 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers(
} else {
{
Map* tmap =
receiver_map->FindElementsKindTransitionedMap(receiver_maps);
receiver_map->FindElementsKindTransitionedMap(*receiver_maps);
if (tmap != nullptr) {
if (receiver_map->is_stable()) {
receiver_map->NotifyLeafMapLayoutChange();

View File

@ -96,7 +96,7 @@ class IC {
void ConfigureVectorState(Handle<Name> name, Handle<Map> map,
Handle<Object> handler);
// Configure the vector for POLYMORPHIC.
void ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
void ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
List<Handle<Object>>* handlers);
char TransitionMarkFromState(IC::State state);
@ -164,16 +164,16 @@ class IC {
}
}
void TargetMaps(MapHandleList* list) {
void TargetMaps(MapHandles* list) {
FindTargetMaps();
for (int i = 0; i < target_maps_.length(); i++) {
list->Add(target_maps_.at(i));
for (Handle<Map> map : target_maps_) {
list->push_back(map);
}
}
Map* FirstTargetMap() {
FindTargetMaps();
return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
return !target_maps_.empty() ? *target_maps_[0] : NULL;
}
Handle<FeedbackVector> vector() const { return nexus()->vector_handle(); }
@ -223,7 +223,7 @@ class IC {
MaybeHandle<Object> maybe_handler_;
ExtraICState extra_ic_state_;
MapHandleList target_maps_;
MapHandles target_maps_;
bool target_maps_set_;
const char* slow_stub_reason_;
@ -328,7 +328,7 @@ class KeyedLoadIC : public LoadIC {
Handle<Object> LoadElementHandler(Handle<Map> receiver_map);
void LoadElementPolymorphicHandlers(MapHandleList* receiver_maps,
void LoadElementPolymorphicHandlers(MapHandles* receiver_maps,
List<Handle<Object>>* handlers);
};
@ -414,7 +414,7 @@ class KeyedStoreIC : public StoreIC {
Handle<Object> StoreElementHandler(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode);
void StoreElementPolymorphicHandlers(MapHandleList* receiver_maps,
void StoreElementPolymorphicHandlers(MapHandles* receiver_maps,
List<Handle<Object>>* handlers,
KeyedAccessStoreMode store_mode);

View File

@ -4832,16 +4832,15 @@ int AccessorInfo::AppendUnique(Handle<Object> descriptors,
valid_descriptors);
}
static bool ContainsMap(MapHandleList* maps, Map* map) {
static bool ContainsMap(MapHandles const& maps, Map* map) {
DCHECK_NOT_NULL(map);
for (int i = 0; i < maps->length(); ++i) {
if (!maps->at(i).is_null() && *maps->at(i) == map) return true;
for (Handle<Map> current : maps) {
if (!current.is_null() && *current == map) return true;
}
return false;
}
Map* Map::FindElementsKindTransitionedMap(MapHandleList* candidates) {
Map* Map::FindElementsKindTransitionedMap(MapHandles const& candidates) {
DisallowHeapAllocation no_allocation;
DisallowDeoptimization no_deoptimization(GetIsolate());

View File

@ -4442,6 +4442,7 @@ class DependentCode: public FixedArray {
class PrototypeInfo;
typedef std::vector<Handle<Map>> MapHandles;
// All heap objects have a Map that describes their structure.
// A Map contains information about:
@ -4964,7 +4965,7 @@ class Map: public HeapObject {
// Returns the transitioned map for this map with the most generic
// elements_kind that's found in |candidates|, or |nullptr| if no match is
// found at all.
Map* FindElementsKindTransitionedMap(MapHandleList* candidates);
Map* FindElementsKindTransitionedMap(MapHandles const& candidates);
inline bool CanTransition();

View File

@ -445,14 +445,14 @@ void TypeFeedbackOracle::CollectReceiverTypes(FeedbackSlot slot,
void TypeFeedbackOracle::CollectReceiverTypes(FeedbackNexus* nexus,
SmallMapList* types) {
MapHandleList maps;
MapHandles maps;
if (nexus->ExtractMaps(&maps) == 0) {
return;
}
types->Reserve(maps.length(), zone());
for (int i = 0; i < maps.length(); i++) {
types->AddMapIfMissing(maps.at(i), zone());
types->Reserve(static_cast<int>(maps.size()), zone());
for (Handle<Map> map : maps) {
types->AddMapIfMissing(map, zone());
}
}

View File

@ -349,9 +349,9 @@ TEST(VectorLoadICStates) {
CompileRun("f({ blarg: 3, torino: 10, foo: 2 })");
CHECK_EQ(POLYMORPHIC, nexus.StateFromFeedback());
MapHandleList maps;
MapHandles maps;
nexus.ExtractMaps(&maps);
CHECK_EQ(4, maps.length());
CHECK_EQ(4, maps.size());
// Finally driven megamorphic.
CompileRun("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })");
@ -428,9 +428,9 @@ TEST(VectorLoadICOnSmi) {
CompileRun("f(o)");
CHECK_EQ(POLYMORPHIC, nexus.StateFromFeedback());
MapHandleList maps;
MapHandles maps;
nexus.ExtractMaps(&maps);
CHECK_EQ(2, maps.length());
CHECK_EQ(2, maps.size());
// One of the maps should be the o map.
v8::MaybeLocal<v8::Value> v8_o =
@ -439,8 +439,7 @@ TEST(VectorLoadICOnSmi) {
Handle<JSObject>::cast(v8::Utils::OpenHandle(*v8_o.ToLocalChecked()));
bool number_map_found = false;
bool o_map_found = false;
for (int i = 0; i < maps.length(); i++) {
Handle<Map> current = maps[i];
for (Handle<Map> current : maps) {
if (*current == number_map)
number_map_found = true;
else if (*current == o->map())
@ -451,9 +450,9 @@ TEST(VectorLoadICOnSmi) {
// The degree of polymorphism doesn't change.
CompileRun("f(100)");
CHECK_EQ(POLYMORPHIC, nexus.StateFromFeedback());
MapHandleList maps2;
MapHandles maps2;
nexus.ExtractMaps(&maps2);
CHECK_EQ(2, maps2.length());
CHECK_EQ(2, maps2.size());
}

View File

@ -1768,9 +1768,9 @@ static void TestReconfigureElementsKind_GeneralizeField(
// Ensure Map::FindElementsKindTransitionedMap() is able to find the
// transitioned map.
{
MapHandleList map_list;
map_list.Add(updated_map);
Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list);
MapHandles map_list;
map_list.push_back(updated_map);
Map* transitioned_map = map2->FindElementsKindTransitionedMap(map_list);
CHECK_EQ(*updated_map, transitioned_map);
}
}
@ -1863,9 +1863,9 @@ static void TestReconfigureElementsKind_GeneralizeFieldTrivial(
// Ensure Map::FindElementsKindTransitionedMap() is able to find the
// transitioned map.
{
MapHandleList map_list;
map_list.Add(updated_map);
Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list);
MapHandles map_list;
map_list.push_back(updated_map);
Map* transitioned_map = map2->FindElementsKindTransitionedMap(map_list);
CHECK_EQ(*updated_map, transitioned_map);
}
}