diff --git a/src/compiler/js-global-object-specialization.cc b/src/compiler/js-global-object-specialization.cc index a06704a..b38aed4 100644 --- a/src/compiler/js-global-object-specialization.cc +++ b/src/compiler/js-global-object-specialization.cc @@ -196,13 +196,18 @@ Type* property_cell_value_type; MachineRepresentation representation = MachineRepresentation::kTagged; if (property_cell_value->IsHeapObject()) { + // We cannot do anything if the {property_cell_value}s map is no + // longer stable. + Handle<Map> property_cell_value_map( + Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); + if (!property_cell_value_map->is_stable()) return NoChange(); + dependencies()->AssumeMapStable(property_cell_value_map); + // Check that the {value} is a HeapObject. value = effect = graph()->NewNode(simplified()->CheckHeapObject(), value, effect, control);
diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc index 16c3639..79e78a5 100644 --- a/src/crankshaft/hydrogen.cc +++ b/src/crankshaft/hydrogen.cc @@ -6518,11 +6518,19 @@ access = access.WithRepresentation(Representation::Smi()); break; case PropertyCellConstantType::kStableMap: { - // The map may no longer be stable, deopt if it's ever different from - // what is currently there, which will allow for restablization. - Handle<Map> map(HeapObject::cast(cell->value())->map()); + // First check that the previous value of the {cell} still has the + // map that we are about to check the new {value} for. If not, then + // the stable map assumption was invalidated and we cannot continue + // with the optimized code. + Handle<HeapObject> cell_value(HeapObject::cast(cell->value())); + Handle<Map> cell_value_map(cell_value->map()); + if (!cell_value_map->is_stable()) { + return Bailout(kUnstableConstantTypeHeapObject); + } + top_info()->dependencies()->AssumeMapStable(cell_value_map); + // Now check that the new {value} is a HeapObject with the same map. Add<HCheckHeapObject>(value); - value = Add<HCheckMaps>(value, map); + value = Add<HCheckMaps>(value, cell_value_map); access = access.WithRepresentation(Representation::HeapObject()); break; }
voidCompilationDependencies::AssumeMapStable(Handle<Map> map){ DCHECK(map->is_stable()); // Do nothing if the map cannot transition. if (map->CanTransition()) { Insert(DependentCode::kPrototypeCheckGroup, map); } }
kPrototypeCheckGroup操作码的注释如下:
1 2 3 4
// Group of code that omit run-time prototype checks for prototypes // described by this map. The group is deoptimized whenever an object // described by this map changes shape (and transitions to a new map), // possibly invalidating the assumptions embedded in the code.