Revert "Create a fast path to get migration target when updating map"
This reverts commit c285380ca8
.
Reason for revert: Lots of dcheck failures on GPU bots, e.g.:
https://ci.chromium.org/p/v8/builders/luci.v8.ci/Win%20V8%20FYI%20Release%20(NVIDIA)/1997
https://ci.chromium.org/p/v8/builders/luci.v8.ci/Linux%20V8%20FYI%20Release%20(NVIDIA)/2770
Original change's description:
> Create a fast path to get migration target when updating map
>
> During map updating, store the pointer to new map in the
> raw_transitions slot of the old map that is deprecated from map
> transition tree. Thus, we can get the migration target directly
> instead of TryReplayPropertyTransitions when updating map.
>
> This can improve Speedometer2.0 Elm-TodoMVC case by ~5% on ATOM
> Chromebook and ~9% on big-core Ubuntu.
>
> Change-Id: I56f9ce5183bbdd567b964890f623ef0ceed9b7db
> Reviewed-on: https://chromium-review.googlesource.com/1233433
> Commit-Queue: Shiyu Zhang <shiyu.zhang@intel.com>
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56303}
TBR=ishell@chromium.org,shiyu.zhang@intel.com
Change-Id: I9b268d662cfa3a7fec577468eafe6570389252bc
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/1253104
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56305}
This commit is contained in:
parent
852a8d35b9
commit
f4d0d7e9fd
@ -170,7 +170,6 @@ Handle<Map> MapUpdater::Update() {
|
||||
if (FindTargetMap() == kEnd) return result_map_;
|
||||
ConstructNewMap();
|
||||
DCHECK_EQ(kEnd, state_);
|
||||
TransitionsAccessor(isolate_, old_map_).SetMigrationTarget(*result_map_);
|
||||
return result_map_;
|
||||
}
|
||||
|
||||
|
@ -2386,7 +2386,6 @@ void TransitionsAccessor::PrintTransitions(std::ostream& os) { // NOLINT
|
||||
switch (encoding()) {
|
||||
case kPrototypeInfo:
|
||||
case kUninitialized:
|
||||
case kMigrationTarget:
|
||||
return;
|
||||
case kWeakRef: {
|
||||
Map* target = Map::cast(raw_transitions_->GetHeapObjectAssumeWeak());
|
||||
|
@ -4882,25 +4882,6 @@ Handle<Map> Map::ReconfigureElementsKind(Isolate* isolate, Handle<Map> map,
|
||||
return mu.ReconfigureElementsKind(new_elements_kind);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
Map* SearchMigrationTarget(Isolate* isolate, Map* old_map) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
DisallowDeoptimization no_deoptimization(isolate);
|
||||
|
||||
Map* target = old_map;
|
||||
do {
|
||||
target = TransitionsAccessor(isolate, target, &no_allocation)
|
||||
.GetMigrationTarget();
|
||||
} while (target != nullptr && target->is_deprecated());
|
||||
SLOW_DCHECK(target == nullptr ||
|
||||
Map::TryUpdateSlow(isolate, old_map) == nullptr ||
|
||||
Map::TryUpdateSlow(isolate, old_map) == target);
|
||||
return target;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// TODO(ishell): Move TryUpdate() and friends to MapUpdater
|
||||
// static
|
||||
MaybeHandle<Map> Map::TryUpdate(Isolate* isolate, Handle<Map> old_map) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
@ -4908,22 +4889,6 @@ MaybeHandle<Map> Map::TryUpdate(Isolate* isolate, Handle<Map> old_map) {
|
||||
|
||||
if (!old_map->is_deprecated()) return old_map;
|
||||
|
||||
Map* target_map = SearchMigrationTarget(isolate, *old_map);
|
||||
if (target_map != nullptr) {
|
||||
return handle(target_map, isolate);
|
||||
}
|
||||
|
||||
Map* new_map = TryUpdateSlow(isolate, *old_map);
|
||||
if (new_map == nullptr) return MaybeHandle<Map>();
|
||||
TransitionsAccessor(isolate, *old_map, &no_allocation)
|
||||
.SetMigrationTarget(new_map);
|
||||
return handle(new_map, isolate);
|
||||
}
|
||||
|
||||
Map* Map::TryUpdateSlow(Isolate* isolate, Map* old_map) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
DisallowDeoptimization no_deoptimization(isolate);
|
||||
|
||||
// Check the state of the root map.
|
||||
Map* root_map = old_map->FindRootMap(isolate);
|
||||
if (root_map->is_deprecated()) {
|
||||
@ -4932,21 +4897,23 @@ Map* Map::TryUpdateSlow(Isolate* isolate, Map* old_map) {
|
||||
DCHECK(constructor->initial_map()->is_dictionary_map());
|
||||
if (constructor->initial_map()->elements_kind() !=
|
||||
old_map->elements_kind()) {
|
||||
return nullptr;
|
||||
return MaybeHandle<Map>();
|
||||
}
|
||||
return constructor->initial_map();
|
||||
return handle(constructor->initial_map(), constructor->GetIsolate());
|
||||
}
|
||||
if (!old_map->EquivalentToForTransition(root_map)) return nullptr;
|
||||
if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
|
||||
|
||||
ElementsKind from_kind = root_map->elements_kind();
|
||||
ElementsKind to_kind = old_map->elements_kind();
|
||||
if (from_kind != to_kind) {
|
||||
// Try to follow existing elements kind transitions.
|
||||
root_map = root_map->LookupElementsTransitionMap(isolate, to_kind);
|
||||
if (root_map == nullptr) return nullptr;
|
||||
if (root_map == nullptr) return MaybeHandle<Map>();
|
||||
// From here on, use the map with correct elements kind as root map.
|
||||
}
|
||||
return root_map->TryReplayPropertyTransitions(isolate, old_map);
|
||||
Map* new_map = root_map->TryReplayPropertyTransitions(isolate, *old_map);
|
||||
if (new_map == nullptr) return MaybeHandle<Map>();
|
||||
return handle(new_map, isolate);
|
||||
}
|
||||
|
||||
Map* Map::TryReplayPropertyTransitions(Isolate* isolate, Map* old_map) {
|
||||
@ -5028,10 +4995,6 @@ Map* Map::TryReplayPropertyTransitions(Isolate* isolate, Map* old_map) {
|
||||
// static
|
||||
Handle<Map> Map::Update(Isolate* isolate, Handle<Map> map) {
|
||||
if (!map->is_deprecated()) return map;
|
||||
Map* target_map = SearchMigrationTarget(isolate, *map);
|
||||
if (target_map != nullptr) {
|
||||
return handle(target_map, isolate);
|
||||
}
|
||||
MapUpdater mu(isolate, map);
|
||||
return mu.Update();
|
||||
}
|
||||
|
@ -632,7 +632,6 @@ class Map : public HeapObject {
|
||||
// is found.
|
||||
static MaybeHandle<Map> TryUpdate(Isolate* isolate,
|
||||
Handle<Map> map) V8_WARN_UNUSED_RESULT;
|
||||
static Map* TryUpdateSlow(Isolate* isolate, Map* map) V8_WARN_UNUSED_RESULT;
|
||||
|
||||
// Returns a non-deprecated version of the input. This method may deprecate
|
||||
// existing maps along the way if encodings conflict. Not for use while
|
||||
|
@ -65,7 +65,6 @@ Name* TransitionsAccessor::GetKey(int transition_number) {
|
||||
switch (encoding()) {
|
||||
case kPrototypeInfo:
|
||||
case kUninitialized:
|
||||
case kMigrationTarget:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
case kWeakRef: {
|
||||
@ -119,7 +118,6 @@ Map* TransitionsAccessor::GetTarget(int transition_number) {
|
||||
switch (encoding()) {
|
||||
case kPrototypeInfo:
|
||||
case kUninitialized:
|
||||
case kMigrationTarget:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
case kWeakRef:
|
||||
|
@ -21,12 +21,9 @@ void TransitionsAccessor::Initialize() {
|
||||
} else if (raw_transitions_->GetHeapObjectIfStrong(&heap_object)) {
|
||||
if (heap_object->IsTransitionArray()) {
|
||||
encoding_ = kFullTransitionArray;
|
||||
} else if (heap_object->IsPrototypeInfo()) {
|
||||
encoding_ = kPrototypeInfo;
|
||||
} else {
|
||||
DCHECK(map_->is_deprecated());
|
||||
DCHECK(heap_object->IsMap());
|
||||
encoding_ = kMigrationTarget;
|
||||
DCHECK(heap_object->IsPrototypeInfo());
|
||||
encoding_ = kPrototypeInfo;
|
||||
}
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
@ -51,7 +48,6 @@ bool TransitionsAccessor::HasSimpleTransitionTo(Map* map) {
|
||||
return raw_transitions_->GetHeapObjectAssumeWeak() == map;
|
||||
case kPrototypeInfo:
|
||||
case kUninitialized:
|
||||
case kMigrationTarget:
|
||||
case kFullTransitionArray:
|
||||
return false;
|
||||
}
|
||||
@ -216,7 +212,6 @@ Map* TransitionsAccessor::SearchTransition(Name* name, PropertyKind kind,
|
||||
switch (encoding()) {
|
||||
case kPrototypeInfo:
|
||||
case kUninitialized:
|
||||
case kMigrationTarget:
|
||||
return nullptr;
|
||||
case kWeakRef: {
|
||||
Map* map = Map::cast(raw_transitions_->GetHeapObjectAssumeWeak());
|
||||
@ -269,7 +264,6 @@ Handle<String> TransitionsAccessor::ExpectedTransitionKey() {
|
||||
switch (encoding()) {
|
||||
case kPrototypeInfo:
|
||||
case kUninitialized:
|
||||
case kMigrationTarget:
|
||||
case kFullTransitionArray:
|
||||
return Handle<String>::null();
|
||||
case kWeakRef: {
|
||||
@ -436,7 +430,6 @@ int TransitionsAccessor::NumberOfTransitions() {
|
||||
switch (encoding()) {
|
||||
case kPrototypeInfo:
|
||||
case kUninitialized:
|
||||
case kMigrationTarget:
|
||||
return 0;
|
||||
case kWeakRef:
|
||||
return 1;
|
||||
@ -447,18 +440,6 @@ int TransitionsAccessor::NumberOfTransitions() {
|
||||
return 0; // Make GCC happy.
|
||||
}
|
||||
|
||||
void TransitionsAccessor::SetMigrationTarget(Map* migration_target) {
|
||||
DCHECK(map_->is_deprecated());
|
||||
ReplaceTransitions(MaybeObject::FromObject(migration_target));
|
||||
}
|
||||
|
||||
Map* TransitionsAccessor::GetMigrationTarget() {
|
||||
if (encoding() == kMigrationTarget) {
|
||||
return map_->raw_transitions()->cast<Map>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TransitionArray::Zap(Isolate* isolate) {
|
||||
MemsetPointer(
|
||||
data_start() + kPrototypeTransitionsIndex,
|
||||
@ -493,8 +474,7 @@ void TransitionsAccessor::SetPrototypeTransitions(
|
||||
|
||||
void TransitionsAccessor::EnsureHasFullTransitionArray() {
|
||||
if (encoding() == kFullTransitionArray) return;
|
||||
int nof =
|
||||
(encoding() == kUninitialized || encoding() == kMigrationTarget) ? 0 : 1;
|
||||
int nof = encoding() == kUninitialized ? 0 : 1;
|
||||
Handle<TransitionArray> result = isolate_->factory()->NewTransitionArray(nof);
|
||||
Reload(); // Reload after possible GC.
|
||||
if (nof == 1) {
|
||||
@ -517,7 +497,6 @@ void TransitionsAccessor::TraverseTransitionTreeInternal(
|
||||
switch (encoding()) {
|
||||
case kPrototypeInfo:
|
||||
case kUninitialized:
|
||||
case kMigrationTarget:
|
||||
break;
|
||||
case kWeakRef: {
|
||||
Map* simple_target =
|
||||
|
@ -106,14 +106,6 @@ class TransitionsAccessor {
|
||||
void PutPrototypeTransition(Handle<Object> prototype, Handle<Map> target_map);
|
||||
Handle<Map> GetPrototypeTransition(Handle<Object> prototype);
|
||||
|
||||
// During the first-time Map::Update and Map::TryUpdate, the migration target
|
||||
// map could be cached in the raw_transitions slot of the old map that is
|
||||
// deprecated from the map transition tree. The next time old map is updated,
|
||||
// we will check this cache slot as a shortcut to get the migration target
|
||||
// map.
|
||||
void SetMigrationTarget(Map* migration_target);
|
||||
Map* GetMigrationTarget();
|
||||
|
||||
#if DEBUG || OBJECT_PRINT
|
||||
void PrintTransitions(std::ostream& os);
|
||||
static void PrintOneTransition(std::ostream& os, Name* key, Map* target);
|
||||
@ -133,7 +125,6 @@ class TransitionsAccessor {
|
||||
enum Encoding {
|
||||
kPrototypeInfo,
|
||||
kUninitialized,
|
||||
kMigrationTarget,
|
||||
kWeakRef,
|
||||
kFullTransitionArray,
|
||||
};
|
||||
|
@ -78,14 +78,6 @@ static Handle<AccessorPair> CreateAccessorPair(bool with_getter,
|
||||
return pair;
|
||||
}
|
||||
|
||||
// Check cached migration target map after Map::Update() and Map::TryUpdate()
|
||||
static void CheckMigrationTarget(Isolate* isolate, Map* old_map, Map* new_map) {
|
||||
Map* target = TransitionsAccessor(isolate, handle(old_map, isolate))
|
||||
.GetMigrationTarget();
|
||||
if (!target) return;
|
||||
CHECK_EQ(new_map, target);
|
||||
CHECK_EQ(Map::TryUpdateSlow(isolate, old_map), target);
|
||||
}
|
||||
|
||||
class Expectations {
|
||||
static const int MAX_PROPERTIES = 10;
|
||||
@ -715,7 +707,6 @@ static void TestGeneralizeField(int detach_property_at_index,
|
||||
// Update all deprecated maps and check that they are now the same.
|
||||
Handle<Map> updated_map = Map::Update(isolate, map);
|
||||
CHECK_EQ(*new_map, *updated_map);
|
||||
CheckMigrationTarget(isolate, *map, *updated_map);
|
||||
}
|
||||
|
||||
static void TestGeneralizeField(const CRFTData& from, const CRFTData& to,
|
||||
@ -976,11 +967,9 @@ TEST(GeneralizeFieldWithAccessorProperties) {
|
||||
// Update all deprecated maps and check that they are now the same.
|
||||
Handle<Map> updated_map = Map::Update(isolate, map);
|
||||
CHECK_EQ(*active_map, *updated_map);
|
||||
CheckMigrationTarget(isolate, *map, *updated_map);
|
||||
for (int i = 0; i < kPropCount; i++) {
|
||||
updated_map = Map::Update(isolate, maps[i]);
|
||||
CHECK_EQ(*active_map, *updated_map);
|
||||
CheckMigrationTarget(isolate, *maps[i], *updated_map);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1071,7 +1060,6 @@ static void TestReconfigureDataFieldAttribute_GeneralizeField(
|
||||
// Update deprecated |map|, it should become |new_map|.
|
||||
Handle<Map> updated_map = Map::Update(isolate, map);
|
||||
CHECK_EQ(*new_map, *updated_map);
|
||||
CheckMigrationTarget(isolate, *map, *updated_map);
|
||||
}
|
||||
|
||||
// This test ensures that trivial field generalization (from HeapObject to
|
||||
@ -1382,7 +1370,6 @@ struct CheckDeprecated {
|
||||
// Update deprecated |map|, it should become |new_map|.
|
||||
Handle<Map> updated_map = Map::Update(isolate, map);
|
||||
CHECK_EQ(*new_map, *updated_map);
|
||||
CheckMigrationTarget(isolate, *map, *updated_map);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1841,7 +1828,6 @@ static void TestReconfigureElementsKind_GeneralizeField(
|
||||
// Update deprecated |map|, it should become |new_map|.
|
||||
Handle<Map> updated_map = Map::Update(isolate, map);
|
||||
CHECK_EQ(*new_map, *updated_map);
|
||||
CheckMigrationTarget(isolate, *map, *updated_map);
|
||||
|
||||
// Ensure Map::FindElementsKindTransitionedMap() is able to find the
|
||||
// transitioned map.
|
||||
@ -2353,11 +2339,9 @@ static void TestGeneralizeFieldWithSpecialTransition(TestConfig& config,
|
||||
// Update all deprecated maps and check that they are now the same.
|
||||
Handle<Map> updated_map = Map::Update(isolate, map);
|
||||
CHECK_EQ(*active_map, *updated_map);
|
||||
CheckMigrationTarget(isolate, *map, *updated_map);
|
||||
for (int i = 0; i < kPropCount; i++) {
|
||||
updated_map = Map::Update(isolate, maps[i]);
|
||||
CHECK_EQ(*active_map, *updated_map);
|
||||
CheckMigrationTarget(isolate, *maps[i], *updated_map);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2639,7 +2623,6 @@ struct FieldGeneralizationChecker {
|
||||
CHECK_NE(*map1, *map2);
|
||||
Handle<Map> updated_map = Map::Update(isolate, map1);
|
||||
CHECK_EQ(*map2, *updated_map);
|
||||
CheckMigrationTarget(isolate, *map1, *updated_map);
|
||||
|
||||
expectations2.SetDataField(descriptor_, attributes_, constness_,
|
||||
representation_, heap_type_);
|
||||
|
Loading…
Reference in New Issue
Block a user