Commit 2359181f authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[constant-tracking] Adjust fast properties heuristic.

With constant field tracking, we get more properties on instance. This
negatively affects the common scenario where objects are used as
module, i.e., they have large number of constant functions as properties.
In that case, we would transition the objects to dictionary mode.

Bug: v8:8361
Change-Id: If4831bd081f3c45be651e051e7375eb275d265b4
Reviewed-on: https://chromium-review.googlesource.com/c/1344110
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57707}
parent 61263dc0
......@@ -4631,6 +4631,26 @@ int Map::NumberOfFields() const {
return result;
}
Map::FieldCounts Map::GetFieldCounts() const {
DescriptorArray* descriptors = instance_descriptors();
int mutable_count = 0;
int const_count = 0;
for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
PropertyDetails details = descriptors->GetDetails(i);
if (details.location() == kField) {
switch (details.constness()) {
case PropertyConstness::kMutable:
mutable_count++;
break;
case PropertyConstness::kConst:
const_count++;
break;
}
}
}
return FieldCounts(mutable_count, const_count);
}
bool Map::HasOutOfObjectProperties() const {
return GetInObjectProperties() < NumberOfFields();
}
......
......@@ -145,10 +145,19 @@ bool Map::IsUnboxedDoubleField(FieldIndex index) const {
bool Map::TooManyFastProperties(StoreOrigin store_origin) const {
if (UnusedPropertyFields() != 0) return false;
if (is_prototype_map()) return false;
int minimum = store_origin == StoreOrigin::kNamed ? 128 : 12;
int limit = Max(minimum, GetInObjectProperties());
int external = NumberOfFields() - GetInObjectProperties();
return external > limit;
if (store_origin == StoreOrigin::kNamed) {
int limit = Max(kMaxFastProperties, GetInObjectProperties());
FieldCounts counts = GetFieldCounts();
// Only count mutable fields so that objects with large numbers of
// constant functions do not go to dictionary mode. That would be bad
// because such objects have often been used as modules.
int external = counts.mutable_count() - GetInObjectProperties();
return external > limit || counts.GetTotal() > kMaxNumberOfDescriptors;
} else {
int limit = Max(kFastPropertiesSoftLimit, GetInObjectProperties());
int external = NumberOfFields() - GetInObjectProperties();
return external > limit;
}
}
PropertyDetails Map::GetLastDescriptorDetails() const {
......
......@@ -453,6 +453,22 @@ class Map : public HeapObjectPtr {
inline int GetInObjectPropertyOffset(int index) const;
class FieldCounts {
public:
FieldCounts(int mutable_count, int const_count)
: mutable_count_(mutable_count), const_count_(const_count) {}
int GetTotal() const { return mutable_count() + const_count(); }
int mutable_count() const { return mutable_count_; }
int const_count() const { return const_count_; }
private:
int mutable_count_;
int const_count_;
};
FieldCounts GetFieldCounts() const;
int NumberOfFields() const;
bool HasOutOfObjectProperties() const;
......
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