Commit 063ada20 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Adding fast path for generalizing maps.

Review URL: https://chromiumcodereview.appspot.com/14629005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14523 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fd9c82a6
......@@ -2460,12 +2460,17 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
// Check the state of the root map.
DescriptorArray* updated_descriptors = updated->instance_descriptors();
int valid = updated->NumberOfOwnDescriptors();
if (updated_descriptors->IsMoreGeneralThan(
verbatim, valid, descriptors, old_descriptors)) {
Representation updated_representation =
updated_descriptors->GetDetails(modify_index).representation();
if (new_representation.fits_into(updated_representation)) return updated;
}
DescriptorArray* new_descriptors;
MaybeObject* maybe_descriptors = updated_descriptors->Merge(
verbatim,
updated->NumberOfOwnDescriptors(),
descriptors,
old_descriptors);
verbatim, valid, descriptors, old_descriptors);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
old_reprepresentation =
......@@ -2477,9 +2482,9 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
verbatim, descriptors, new_descriptors);
int split_descriptors = split_map->NumberOfOwnDescriptors();
// Check whether |split_map| matches what we were looking for. If so, return
// it.
if (descriptors == split_descriptors) return split_map;
// This is shadowed by |updated_descriptors| being more general than
// |old_descriptors|.
ASSERT(descriptors != split_descriptors);
int descriptor = split_descriptors;
split_map->DeprecateTarget(
......@@ -7260,7 +7265,7 @@ void DescriptorArray::CopyFrom(int dst_index,
}
// Generalize the |other| descriptor array by merging it with the (at least
// Generalize the |other| descriptor array by merging it into the (at least
// partly) updated |this| descriptor array.
// The method merges two descriptor array in three parts. Both descriptor arrays
// are identical up to |verbatim|. They also overlap in keys up to |valid|.
......@@ -7343,6 +7348,37 @@ MaybeObject* DescriptorArray::Merge(int verbatim,
}
// Checks whether a merge of |other| into |this| would return a copy of |this|.
bool DescriptorArray::IsMoreGeneralThan(int verbatim,
int valid,
int new_size,
DescriptorArray* other) {
ASSERT(verbatim <= valid);
ASSERT(valid <= new_size);
if (valid != new_size) return false;
for (int descriptor = verbatim; descriptor < valid; descriptor++) {
PropertyDetails details = GetDetails(descriptor);
PropertyDetails other_details = other->GetDetails(descriptor);
if (details.type() != other_details.type()) {
if (details.type() != FIELD ||
other_details.type() != CONSTANT_FUNCTION) {
return false;
}
} else if (details.type() == CONSTANT_FUNCTION) {
if (GetValue(descriptor) != other->GetValue(descriptor)) {
return false;
}
} else if (!other_details.representation().fits_into(
details.representation())) {
return false;
}
}
return true;
}
// We need the whiteness witness since sort will reshuffle the entries in the
// descriptor array. If the descriptor array were to be black, the shuffling
// would move a slot that was already recorded as pointing into an evacuation
......
......@@ -2809,6 +2809,11 @@ class DescriptorArray: public FixedArray {
int new_size,
DescriptorArray* other);
bool IsMoreGeneralThan(int verbatim,
int valid,
int new_size,
DescriptorArray* other);
MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index);
// Sort the instance descriptors by the hash codes of their keys.
......
......@@ -99,16 +99,20 @@ class Representation {
static Representation FromKind(Kind kind) { return Representation(kind); }
bool Equals(const Representation& other) {
bool Equals(const Representation& other) const {
return kind_ == other.kind_;
}
bool is_more_general_than(const Representation& other) {
bool is_more_general_than(const Representation& other) const {
ASSERT(kind_ != kExternal);
ASSERT(other.kind_ != kExternal);
return kind_ > other.kind_;
}
bool fits_into(const Representation& other) const {
return other.is_more_general_than(*this) || other.Equals(*this);
}
Representation generalize(Representation other) {
if (is_more_general_than(other)) {
return *this;
......
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