Commit 73b3bb58 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Brokerize CompilationDependencies.

Bug: v8:7790
Change-Id: I747dccb8dcae74c5c0837c0cd7f3dd285a4bd9c0
Reviewed-on: https://chromium-review.googlesource.com/1140304Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54497}
parent 64517a23
......@@ -237,11 +237,11 @@ Handle<Cell> PropertyAccessInfo::export_cell() const {
return Handle<Cell>::cast(constant_);
}
AccessInfoFactory::AccessInfoFactory(CompilationDependencies* dependencies,
const JSHeapBroker* js_heap_broker,
AccessInfoFactory::AccessInfoFactory(const JSHeapBroker* js_heap_broker,
CompilationDependencies* dependencies,
Handle<Context> native_context, Zone* zone)
: dependencies_(dependencies),
js_heap_broker_(js_heap_broker),
: js_heap_broker_(js_heap_broker),
dependencies_(dependencies),
native_context_(native_context),
isolate_(native_context->GetIsolate()),
type_cache_(TypeCache::Get()),
......@@ -396,7 +396,8 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
// The field type was cleared by the GC, so we don't know anything
// about the contents now.
} else if (descriptors_field_type->IsClass()) {
dependencies()->DependOnFieldType(map, number);
dependencies()->DependOnFieldType(MapRef(js_heap_broker(), map),
number);
// Remember the field map, and try to infer a useful type.
field_type = Type::For(js_heap_broker(),
descriptors_field_type->AsClass());
......@@ -699,14 +700,15 @@ bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
// Store is not safe if the field type was cleared.
return false;
} else if (descriptors_field_type->IsClass()) {
dependencies()->DependOnFieldType(transition_map, number);
dependencies()->DependOnFieldType(
MapRef(js_heap_broker(), transition_map), number);
// Remember the field map, and try to infer a useful type.
field_type =
Type::For(js_heap_broker(), descriptors_field_type->AsClass());
field_map = descriptors_field_type->AsClass();
}
}
dependencies()->DependOnTransition(transition_map);
dependencies()->DependOnTransition(MapRef(js_heap_broker(), transition_map));
// Transitioning stores are never stores to constant fields.
*access_info = PropertyAccessInfo::DataField(
PropertyConstness::kMutable, MapHandles{map}, field_index,
......
......@@ -140,8 +140,9 @@ class PropertyAccessInfo final {
// Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
class AccessInfoFactory final {
public:
AccessInfoFactory(CompilationDependencies* dependencies,
const JSHeapBroker* js_heap_broker,
AccessInfoFactory(const JSHeapBroker* js_heap_broker,
CompilationDependencies* dependencies,
Handle<Context> native_context, Zone* zone);
bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
......@@ -174,8 +175,8 @@ class AccessInfoFactory final {
Handle<Context> native_context() const { return native_context_; }
Zone* zone() const { return zone_; }
CompilationDependencies* const dependencies_;
const JSHeapBroker* const js_heap_broker_;
CompilationDependencies* const dependencies_;
Handle<Context> const native_context_;
Isolate* const isolate_;
TypeCache const& type_cache_;
......
......@@ -12,278 +12,309 @@ namespace internal {
namespace compiler {
CompilationDependencies::CompilationDependencies(Isolate* isolate, Zone* zone)
: isolate_(isolate), zone_(zone), dependencies_(zone) {}
: zone_(zone), dependencies_(zone) {}
class CompilationDependencies::Dependency : public ZoneObject {
public:
virtual bool IsSane() const = 0;
virtual bool IsValid() const = 0;
virtual void Install(Isolate* isolate, Handle<WeakCell> code) = 0;
};
class InitialMapDependency final : public CompilationDependencies::Dependency {
public:
InitialMapDependency(Handle<JSFunction> function, Handle<Map> initial_map)
InitialMapDependency(JSFunctionRef function, MapRef initial_map)
: function_(function), initial_map_(initial_map) {
DCHECK(IsValid());
DCHECK(IsSane());
}
bool IsSane() const override {
DisallowHeapAccess no_heap_access;
CHECK(function_.has_initial_map());
return function_.initial_map().equals(initial_map_);
}
bool IsValid() const override {
DisallowHeapAllocation no_heap_allocation;
DCHECK(function_->has_initial_map());
return *initial_map_ == function_->initial_map();
Handle<JSFunction> function = function_.object<JSFunction>();
CHECK(function->has_initial_map());
return function->initial_map() == *initial_map_.object<Map>();
}
void Install(Isolate* isolate, Handle<WeakCell> code) override {
DCHECK(IsValid());
DependentCode::InstallDependency(isolate, code, initial_map_,
DependentCode::InstallDependency(isolate, code, initial_map_.object<Map>(),
DependentCode::kInitialMapChangedGroup);
}
private:
Handle<JSFunction> function_;
Handle<Map> initial_map_;
JSFunctionRef function_;
MapRef initial_map_;
};
class StableMapDependency final : public CompilationDependencies::Dependency {
public:
explicit StableMapDependency(Handle<Map> map) : map_(map) {
DCHECK(IsValid());
explicit StableMapDependency(const MapRef& map) : map_(map) {
DCHECK(IsSane());
}
bool IsValid() const override {
DisallowHeapAllocation no_heap_allocation;
return map_->is_stable();
bool IsSane() const override {
DisallowHeapAccess no_heap_access;
return map_.is_stable();
}
bool IsValid() const override { return map_.object<Map>()->is_stable(); }
void Install(Isolate* isolate, Handle<WeakCell> code) override {
DCHECK(IsValid());
DependentCode::InstallDependency(isolate, code, map_,
DependentCode::InstallDependency(isolate, code, map_.object<Map>(),
DependentCode::kPrototypeCheckGroup);
}
private:
Handle<Map> map_;
MapRef map_;
};
class TransitionDependency final : public CompilationDependencies::Dependency {
public:
explicit TransitionDependency(Handle<Map> map) : map_(map) {
DCHECK(IsValid());
explicit TransitionDependency(const MapRef& map) : map_(map) {
DCHECK(IsSane());
}
bool IsValid() const override {
DisallowHeapAllocation no_heap_allocation;
return !map_->is_deprecated();
bool IsSane() const override {
DisallowHeapAccess no_heap_access;
return !map_.is_deprecated();
}
bool IsValid() const override { return !map_.object<Map>()->is_deprecated(); }
void Install(Isolate* isolate, Handle<WeakCell> code) override {
DCHECK(IsValid());
DependentCode::InstallDependency(isolate, code, map_,
DependentCode::InstallDependency(isolate, code, map_.object<Map>(),
DependentCode::kTransitionGroup);
}
private:
Handle<Map> map_;
MapRef map_;
};
class PretenureModeDependency final
: public CompilationDependencies::Dependency {
public:
PretenureModeDependency(Handle<AllocationSite> site, PretenureFlag mode)
PretenureModeDependency(const AllocationSiteRef& site, PretenureFlag mode)
: site_(site), mode_(mode) {
DCHECK(IsValid());
DCHECK(IsSane());
}
bool IsSane() const override {
DisallowHeapAccess no_heap_access;
return mode_ == site_.GetPretenureMode();
}
bool IsValid() const override {
DisallowHeapAllocation no_heap_allocation;
return mode_ == site_->GetPretenureMode();
return mode_ == site_.object<AllocationSite>()->GetPretenureMode();
}
void Install(Isolate* isolate, Handle<WeakCell> code) override {
DCHECK(IsValid());
DependentCode::InstallDependency(
isolate, code, site_,
isolate, code, site_.object<AllocationSite>(),
DependentCode::kAllocationSiteTenuringChangedGroup);
}
private:
Handle<AllocationSite> site_;
AllocationSiteRef site_;
PretenureFlag mode_;
};
class FieldTypeDependency final : public CompilationDependencies::Dependency {
public:
FieldTypeDependency(Isolate* isolate, Handle<Map> owner, int descriptor,
Handle<FieldType> type)
: isolate_(isolate), owner_(owner), descriptor_(descriptor), type_(type) {
DCHECK(IsValid());
FieldTypeDependency(const MapRef& owner, int descriptor,
const FieldTypeRef& type)
: owner_(owner), descriptor_(descriptor), type_(type) {
DCHECK(IsSane());
}
bool IsSane() const override {
DisallowHeapAccess no_heap_access;
CHECK(owner_.equals(owner_.FindFieldOwner(descriptor_)));
return type_.equals(owner_.GetFieldType(descriptor_));
}
bool IsValid() const override {
DisallowHeapAllocation no_heap_allocation;
CHECK_EQ(*owner_, owner_->FindFieldOwner(isolate_, descriptor_));
return *type_ == owner_->instance_descriptors()->GetFieldType(descriptor_);
Handle<Map> owner = owner_.object<Map>();
Handle<FieldType> type = type_.object<FieldType>();
return *type == owner->instance_descriptors()->GetFieldType(descriptor_);
}
void Install(Isolate* isolate, Handle<WeakCell> code) override {
DCHECK(IsValid());
DependentCode::InstallDependency(isolate, code, owner_,
DependentCode::InstallDependency(isolate, code, owner_.object<Map>(),
DependentCode::kFieldOwnerGroup);
}
private:
Isolate* isolate_;
Handle<Map> owner_;
MapRef owner_;
int descriptor_;
Handle<FieldType> type_;
FieldTypeRef type_;
};
class GlobalPropertyDependency final
: public CompilationDependencies::Dependency {
public:
GlobalPropertyDependency(Handle<PropertyCell> cell, PropertyCellType type,
GlobalPropertyDependency(const PropertyCellRef& cell, PropertyCellType type,
bool read_only)
: cell_(cell), type_(type), read_only_(read_only) {
DCHECK(IsValid());
DCHECK(IsSane());
}
bool IsSane() const override {
DisallowHeapAccess no_heap_access;
return type_ == cell_.property_details().cell_type() &&
read_only_ == cell_.property_details().IsReadOnly();
}
bool IsValid() const override {
DisallowHeapAllocation no_heap_allocation;
return type_ == cell_->property_details().cell_type() &&
read_only_ == cell_->property_details().IsReadOnly();
Handle<PropertyCell> cell = cell_.object<PropertyCell>();
return type_ == cell->property_details().cell_type() &&
read_only_ == cell->property_details().IsReadOnly();
}
void Install(Isolate* isolate, Handle<WeakCell> code) override {
DCHECK(IsValid());
DependentCode::InstallDependency(isolate, code, cell_,
DependentCode::InstallDependency(isolate, code,
cell_.object<PropertyCell>(),
DependentCode::kPropertyCellChangedGroup);
}
private:
Handle<PropertyCell> cell_;
PropertyCellRef cell_;
PropertyCellType type_;
bool read_only_;
};
class ProtectorDependency final : public CompilationDependencies::Dependency {
public:
explicit ProtectorDependency(Handle<PropertyCell> cell) : cell_(cell) {
DCHECK(IsValid());
explicit ProtectorDependency(const PropertyCellRef& cell) : cell_(cell) {
DCHECK(IsSane());
}
bool IsSane() const override {
DisallowHeapAccess no_heap_access;
return cell_.value().IsSmi() &&
cell_.value().AsSmi() == Isolate::kProtectorValid;
}
bool IsValid() const override {
DisallowHeapAllocation no_heap_allocation;
return cell_->value() == Smi::FromInt(Isolate::kProtectorValid);
Handle<PropertyCell> cell = cell_.object<PropertyCell>();
return cell->value() == Smi::FromInt(Isolate::kProtectorValid);
}
void Install(Isolate* isolate, Handle<WeakCell> code) override {
DCHECK(IsValid());
DependentCode::InstallDependency(isolate, code, cell_,
DependentCode::InstallDependency(isolate, code,
cell_.object<PropertyCell>(),
DependentCode::kPropertyCellChangedGroup);
}
private:
Handle<PropertyCell> cell_;
PropertyCellRef cell_;
};
class ElementsKindDependency final
: public CompilationDependencies::Dependency {
public:
ElementsKindDependency(Handle<AllocationSite> site, ElementsKind kind)
ElementsKindDependency(const AllocationSiteRef& site, ElementsKind kind)
: site_(site), kind_(kind) {
DCHECK(IsValid());
DCHECK(IsSane());
}
bool IsValid() const override {
DisallowHeapAllocation no_heap_allocation;
bool IsSane() const override {
DisallowHeapAccess no_heap_access;
DCHECK(AllocationSite::ShouldTrack(kind_));
ElementsKind kind = site_->PointsToLiteral()
? site_->boilerplate()->GetElementsKind()
: site_->GetElementsKind();
ElementsKind kind = site_.PointsToLiteral()
? site_.boilerplate().GetElementsKind()
: site_.GetElementsKind();
return kind_ == kind;
}
bool IsValid() const override {
Handle<AllocationSite> site = site_.object<AllocationSite>();
ElementsKind kind = site->PointsToLiteral()
? site->boilerplate()->GetElementsKind()
: site->GetElementsKind();
return kind_ == kind;
}
void Install(Isolate* isolate, Handle<WeakCell> code) override {
DCHECK(IsValid());
DependentCode::InstallDependency(
isolate, code, site_,
isolate, code, site_.object<AllocationSite>(),
DependentCode::kAllocationSiteTransitionChangedGroup);
}
private:
Handle<AllocationSite> site_;
AllocationSiteRef site_;
ElementsKind kind_;
};
Handle<Map> CompilationDependencies::DependOnInitialMap(
Handle<JSFunction> function) {
Handle<Map> map(function->initial_map(), function->GetIsolate());
MapRef CompilationDependencies::DependOnInitialMap(
const JSFunctionRef& function) {
MapRef map = function.initial_map();
dependencies_.push_front(new (zone_) InitialMapDependency(function, map));
return map;
}
void CompilationDependencies::DependOnStableMap(Handle<Map> map) {
if (map->CanTransition()) {
void CompilationDependencies::DependOnStableMap(const MapRef& map) {
if (map.CanTransition()) {
dependencies_.push_front(new (zone_) StableMapDependency(map));
} else {
DCHECK(map->is_stable());
DCHECK(map.is_stable());
}
}
void CompilationDependencies::DependOnTransition(Handle<Map> target_map) {
if (target_map->CanBeDeprecated()) {
void CompilationDependencies::DependOnTransition(const MapRef& target_map) {
if (target_map.CanBeDeprecated()) {
dependencies_.push_front(new (zone_) TransitionDependency(target_map));
} else {
DCHECK(!target_map->is_deprecated());
DCHECK(!target_map.is_deprecated());
}
}
PretenureFlag CompilationDependencies::DependOnPretenureMode(
Handle<AllocationSite> site) {
PretenureFlag mode = site->GetPretenureMode();
const AllocationSiteRef& site) {
PretenureFlag mode = site.GetPretenureMode();
dependencies_.push_front(new (zone_) PretenureModeDependency(site, mode));
return mode;
}
void CompilationDependencies::DependOnFieldType(Handle<Map> map,
void CompilationDependencies::DependOnFieldType(const MapRef& map,
int descriptor) {
Handle<Map> owner(map->FindFieldOwner(isolate_, descriptor), isolate_);
Handle<FieldType> type(
owner->instance_descriptors()->GetFieldType(descriptor), isolate_);
DCHECK_EQ(*type, map->instance_descriptors()->GetFieldType(descriptor));
dependencies_.push_front(
new (zone_) FieldTypeDependency(isolate_, owner, descriptor, type));
}
void CompilationDependencies::DependOnFieldType(const LookupIterator* it) {
Handle<Map> owner = it->GetFieldOwnerMap();
int descriptor = it->GetFieldDescriptorIndex();
Handle<FieldType> type = it->GetFieldType();
CHECK_EQ(*type,
it->GetHolder<Map>()->map()->instance_descriptors()->GetFieldType(
descriptor));
dependencies_.push_front(
new (zone_) FieldTypeDependency(isolate_, owner, descriptor, type));
MapRef owner = map.FindFieldOwner(descriptor);
FieldTypeRef type = owner.GetFieldType(descriptor);
DCHECK(type.equals(map.GetFieldType(descriptor)));
dependencies_.push_front(new (zone_)
FieldTypeDependency(owner, descriptor, type));
}
void CompilationDependencies::DependOnGlobalProperty(
Handle<PropertyCell> cell) {
PropertyCellType type = cell->property_details().cell_type();
bool read_only = cell->property_details().IsReadOnly();
const PropertyCellRef& cell) {
PropertyCellType type = cell.property_details().cell_type();
bool read_only = cell.property_details().IsReadOnly();
dependencies_.push_front(new (zone_)
GlobalPropertyDependency(cell, type, read_only));
}
void CompilationDependencies::DependOnProtector(Handle<PropertyCell> cell) {
void CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) {
dependencies_.push_front(new (zone_) ProtectorDependency(cell));
}
void CompilationDependencies::DependOnElementsKind(
Handle<AllocationSite> site) {
const AllocationSiteRef& site) {
// Do nothing if the object doesn't have any useful element transitions left.
ElementsKind kind = site->PointsToLiteral()
? site->boilerplate()->GetElementsKind()
: site->GetElementsKind();
ElementsKind kind = site.PointsToLiteral()
? site.boilerplate().GetElementsKind()
: site.GetElementsKind();
if (AllocationSite::ShouldTrack(kind)) {
dependencies_.push_front(new (zone_) ElementsKindDependency(site, kind));
}
......@@ -297,6 +328,8 @@ bool CompilationDependencies::AreValid() const {
}
bool CompilationDependencies::Commit(Handle<Code> code) {
Isolate* isolate = code->GetIsolate();
// Check validity of all dependencies first, such that we can abort before
// installing anything.
if (!AreValid()) {
......@@ -306,21 +339,22 @@ bool CompilationDependencies::Commit(Handle<Code> code) {
Handle<WeakCell> cell = Code::WeakCellFor(code);
for (auto dep : dependencies_) {
dep->Install(isolate_, cell);
dep->Install(isolate, cell);
}
dependencies_.clear();
return true;
}
namespace {
void DependOnStablePrototypeChain(Isolate* isolate,
void DependOnStablePrototypeChain(const JSHeapBroker* broker,
CompilationDependencies* deps,
Handle<Map> map,
MaybeHandle<JSReceiver> last_prototype) {
for (PrototypeIterator i(isolate, map); !i.IsAtEnd(); i.Advance()) {
for (PrototypeIterator i(broker->isolate(), map); !i.IsAtEnd(); i.Advance()) {
Handle<JSReceiver> const current =
PrototypeIterator::GetCurrent<JSReceiver>(i);
deps->DependOnStableMap(handle(current->map(), isolate));
deps->DependOnStableMap(
MapRef(broker, handle(current->map(), broker->isolate())));
Handle<JSReceiver> last;
if (last_prototype.ToHandle(&last) && last.is_identical_to(current)) {
break;
......@@ -330,8 +364,9 @@ void DependOnStablePrototypeChain(Isolate* isolate,
} // namespace
void CompilationDependencies::DependOnStablePrototypeChains(
Handle<Context> native_context,
const JSHeapBroker* broker, Handle<Context> native_context,
std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) {
Isolate* isolate = holder->GetIsolate();
// Determine actual holder and perform prototype chain checks.
for (auto map : receiver_maps) {
// Perform the implicit ToObject for primitives here.
......@@ -339,20 +374,21 @@ void CompilationDependencies::DependOnStablePrototypeChains(
Handle<JSFunction> constructor;
if (Map::GetConstructorFunction(map, native_context)
.ToHandle(&constructor)) {
map = handle(constructor->initial_map(), isolate_);
map = handle(constructor->initial_map(), isolate);
}
DependOnStablePrototypeChain(isolate_, this, map, holder);
DependOnStablePrototypeChain(broker, this, map, holder);
}
}
void CompilationDependencies::DependOnElementsKinds(
Handle<AllocationSite> site) {
const AllocationSiteRef& site) {
AllocationSiteRef current = site;
while (true) {
DependOnElementsKind(site);
if (!site->nested_site()->IsAllocationSite()) break;
site = handle(AllocationSite::cast(site->nested_site()), isolate_);
DependOnElementsKind(current);
if (!current.nested_site().IsAllocationSite()) break;
current = current.nested_site().AsAllocationSite();
}
CHECK_EQ(site->nested_site(), Smi::kZero);
CHECK_EQ(current.nested_site().AsSmi(), 0);
}
} // namespace compiler
......
......@@ -5,6 +5,7 @@
#ifndef V8_COMPILER_COMPILATION_DEPENDENCIES_H_
#define V8_COMPILER_COMPILATION_DEPENDENCIES_H_
#include "src/compiler/js-heap-broker.h"
#include "src/objects.h"
#include "src/zone/zone-containers.h"
......@@ -21,42 +22,42 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject {
// Return the initial map of {function} and record the assumption that it
// stays the intial map.
Handle<Map> DependOnInitialMap(Handle<JSFunction> function);
MapRef DependOnInitialMap(const JSFunctionRef& function);
// Record the assumption that {map} stays stable.
void DependOnStableMap(Handle<Map> map);
void DependOnStableMap(const MapRef& map);
// Record the assumption that {target_map} can be transitioned to, i.e., that
// it does not become deprecated.
void DependOnTransition(Handle<Map> target_map);
void DependOnTransition(const MapRef& target_map);
// Return the pretenure mode of {site} and record the assumption that it does
// not change.
PretenureFlag DependOnPretenureMode(Handle<AllocationSite> site);
PretenureFlag DependOnPretenureMode(const AllocationSiteRef& site);
// Record the assumption that the field type of a field does not change. The
// field is identified by the argument(s).
void DependOnFieldType(Handle<Map> map, int descriptor);
void DependOnFieldType(const LookupIterator* it);
// field is identified by the arguments.
void DependOnFieldType(const MapRef& map, int descriptor);
// Record the assumption that neither {cell}'s {CellType} changes, nor the
// {IsReadOnly()} flag of {cell}'s {PropertyDetails}.
void DependOnGlobalProperty(Handle<PropertyCell> cell);
void DependOnGlobalProperty(const PropertyCellRef& cell);
// Record the assumption that the protector remains valid.
void DependOnProtector(Handle<PropertyCell> cell);
void DependOnProtector(const PropertyCellRef& cell);
// Record the assumption that {site}'s {ElementsKind} doesn't change.
void DependOnElementsKind(Handle<AllocationSite> site);
void DependOnElementsKind(const AllocationSiteRef& site);
// Depend on the stability of (the maps of) all prototypes of every class in
// {receiver_type} up to (and including) the {holder}.
// TODO(neis): Fully brokerize!
void DependOnStablePrototypeChains(
Handle<Context> native_context,
const JSHeapBroker* broker, Handle<Context> native_context,
std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder);
// Like DependOnElementsKind but also applies to all nested allocation sites.
void DependOnElementsKinds(Handle<AllocationSite> site);
void DependOnElementsKinds(const AllocationSiteRef& site);
// Exposed only for testing purposes.
bool AreValid() const;
......@@ -65,7 +66,6 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject {
class Dependency;
private:
Isolate* isolate_;
Zone* zone_;
ZoneForwardList<Dependency*> dependencies_;
};
......
......@@ -594,7 +594,8 @@ Reduction JSCallReducer::ReduceObjectGetPrototype(Node* node, Node* object) {
}
if (result == NodeProperties::kUnreliableReceiverMaps) {
for (size_t i = 0; i < object_maps.size(); ++i) {
dependencies()->DependOnStableMap(object_maps[i]);
dependencies()->DependOnStableMap(
MapRef(js_heap_broker(), object_maps[i]));
}
}
Node* value = jsgraph()->Constant(candidate_prototype);
......@@ -1050,7 +1051,8 @@ Reduction JSCallReducer::ReduceArrayForEach(Node* node,
// Install code dependencies on the {receiver} prototype maps and the
// global array protector cell.
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
// If we have unreliable maps, we need a map check.
if (result == NodeProperties::kUnreliableReceiverMaps) {
......@@ -1234,7 +1236,8 @@ Reduction JSCallReducer::ReduceArrayReduce(Node* node,
// Install code dependencies on the {receiver} prototype maps and the
// global array protector cell.
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
// If we have unreliable maps, we need a map check.
if (result == NodeProperties::kUnreliableReceiverMaps) {
......@@ -1504,7 +1507,8 @@ Reduction JSCallReducer::ReduceArrayMap(Node* node,
if (receiver_map->elements_kind() != kind) return NoChange();
}
dependencies()->DependOnProtector(factory()->array_species_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->array_species_protector()));
Handle<JSFunction> handle_constructor(
JSFunction::cast(
......@@ -1711,7 +1715,8 @@ Reduction JSCallReducer::ReduceArrayFilter(Node* node,
if (receiver_map->elements_kind() != kind) return NoChange();
}
dependencies()->DependOnProtector(factory()->array_species_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->array_species_protector()));
Handle<Map> initial_map(
Map::cast(native_context()->GetInitialJSArrayMap(packed_kind)),
......@@ -1989,7 +1994,8 @@ Reduction JSCallReducer::ReduceArrayFind(Node* node, ArrayFindVariant variant,
// Install code dependencies on the {receiver} prototype maps and the
// global array protector cell.
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
// If we have unreliable maps, we need a map check.
if (result == NodeProperties::kUnreliableReceiverMaps) {
......@@ -2304,7 +2310,8 @@ Reduction JSCallReducer::ReduceArrayEvery(Node* node,
if (receiver_map->elements_kind() != kind) return NoChange();
}
dependencies()->DependOnProtector(factory()->array_species_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->array_species_protector()));
// If we have unreliable maps, we need a map check.
if (result == NodeProperties::kUnreliableReceiverMaps) {
......@@ -2644,7 +2651,8 @@ Reduction JSCallReducer::ReduceArraySome(Node* node,
if (receiver_map->elements_kind() != kind) return NoChange();
}
dependencies()->DependOnProtector(factory()->array_species_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->array_species_protector()));
Node* k = jsgraph()->ZeroConstant();
......@@ -2892,7 +2900,8 @@ Reduction JSCallReducer::ReduceCallApiFunction(
// Install stability dependencies for unreliable {receiver_maps}.
if (result == NodeProperties::kUnreliableReceiverMaps) {
for (size_t i = 0; i < receiver_maps.size(); ++i) {
dependencies()->DependOnStableMap(receiver_maps[i]);
dependencies()->DependOnStableMap(
MapRef(js_heap_broker(), receiver_maps[i]));
}
}
......@@ -3062,7 +3071,8 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread(
// that no one messed with the %ArrayIteratorPrototype%.next method.
if (node->opcode() == IrOpcode::kJSCallWithSpread ||
node->opcode() == IrOpcode::kJSConstructWithSpread) {
dependencies()->DependOnProtector(factory()->array_iterator_protector());
dependencies()->DependOnProtector(PropertyCellRef(
js_heap_broker(), factory()->array_iterator_protector()));
}
// Remove the {arguments_list} input from the {node}.
......@@ -4336,7 +4346,8 @@ Reduction JSCallReducer::ReduceArrayPrototypePush(Node* node) {
}
// Install code dependencies on the {receiver} global array protector cell.
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
// If the {receiver_maps} information is not reliable, we need
// to check that the {receiver} still has one of these maps.
......@@ -4450,7 +4461,8 @@ Reduction JSCallReducer::ReduceArrayPrototypePop(Node* node) {
}
// Install code dependencies on the {receiver} global array protector cell.
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
// If the {receiver_maps} information is not reliable, we need
// to check that the {receiver} still has one of these maps.
......@@ -4568,7 +4580,8 @@ Reduction JSCallReducer::ReduceArrayPrototypeShift(Node* node) {
}
// Install code dependencies on the {receiver} global array protector cell.
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
// If the {receiver_maps} information is not reliable, we need
// to check that the {receiver} still has one of these maps.
......@@ -4849,7 +4862,8 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) {
// Install code dependency on the array protector for holey arrays.
if (IsHoleyElementsKind(elements_kind)) {
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
}
// Load the (current) {iterated_object} from the {iterator}; this might be
......@@ -4873,8 +4887,8 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) {
if (isolate()->IsArrayBufferNeuteringIntact()) {
// Add a code dependency so we are deoptimized in case an ArrayBuffer
// gets neutered.
dependencies()->DependOnProtector(
factory()->array_buffer_neutering_protector());
dependencies()->DependOnProtector(PropertyCellRef(
js_heap_broker(), factory()->array_buffer_neutering_protector()));
} else {
// Deoptimize if the array buffer was neutered.
Node* buffer = effect = graph()->NewNode(
......@@ -5359,7 +5373,8 @@ Reduction JSCallReducer::ReduceAsyncFunctionPromiseCreate(Node* node) {
if (!isolate()->IsPromiseHookProtectorIntact()) return NoChange();
// Install a code dependency on the promise hook protector cell.
dependencies()->DependOnProtector(factory()->promise_hook_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->promise_hook_protector()));
// Morph this {node} into a JSCreatePromise node.
RelaxControls(node);
......@@ -5374,7 +5389,8 @@ Reduction JSCallReducer::ReduceAsyncFunctionPromiseRelease(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
if (!isolate()->IsPromiseHookProtectorIntact()) return NoChange();
dependencies()->DependOnProtector(factory()->promise_hook_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->promise_hook_protector()));
// The AsyncFunctionPromiseRelease builtin is a no-op as long as neither
// the debugger is active nor any promise hook has been installed (ever).
......@@ -5429,7 +5445,8 @@ Reduction JSCallReducer::ReducePromiseConstructor(Node* node) {
// Only handle builtins Promises, not subclasses.
if (target != new_target) return NoChange();
dependencies()->DependOnProtector(factory()->promise_hook_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->promise_hook_protector()));
Handle<SharedFunctionInfo> promise_shared(
handle(native_context()->promise_function()->shared(), isolate()));
......@@ -5586,7 +5603,8 @@ Reduction JSCallReducer::ReducePromiseInternalConstructor(Node* node) {
// Check that promises aren't being observed through (debug) hooks.
if (!isolate()->IsPromiseHookProtectorIntact()) return NoChange();
dependencies()->DependOnProtector(factory()->promise_hook_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->promise_hook_protector()));
// Create a new pending promise.
Node* value = effect =
......@@ -5678,7 +5696,8 @@ Reduction JSCallReducer::ReducePromisePrototypeCatch(Node* node) {
}
}
dependencies()->DependOnProtector(factory()->promise_then_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->promise_then_protector()));
// If the {receiver_maps} aren't reliable, we need to repeat the
// map check here, guarded by the CALL_IC.
......@@ -5754,9 +5773,12 @@ Reduction JSCallReducer::ReducePromisePrototypeFinally(Node* node) {
}
}
dependencies()->DependOnProtector(factory()->promise_hook_protector());
dependencies()->DependOnProtector(factory()->promise_then_protector());
dependencies()->DependOnProtector(factory()->promise_species_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->promise_hook_protector()));
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->promise_then_protector()));
dependencies()->DependOnProtector(PropertyCellRef(
js_heap_broker(), factory()->promise_species_protector()));
// If the {receiver_maps} aren't reliable, we need to repeat the
// map check here, guarded by the CALL_IC.
......@@ -5906,8 +5928,10 @@ Reduction JSCallReducer::ReducePromisePrototypeThen(Node* node) {
}
}
dependencies()->DependOnProtector(factory()->promise_hook_protector());
dependencies()->DependOnProtector(factory()->promise_species_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->promise_hook_protector()));
dependencies()->DependOnProtector(PropertyCellRef(
js_heap_broker(), factory()->promise_species_protector()));
// If the {receiver_maps} aren't reliable, we need to repeat the
// map check here, guarded by the CALL_IC.
......@@ -6584,8 +6608,8 @@ Reduction JSCallReducer::ReduceArrayBufferViewAccessor(
if (isolate()->IsArrayBufferNeuteringIntact()) {
// Add a code dependency so we are deoptimized in case an ArrayBuffer
// gets neutered.
dependencies()->DependOnProtector(
factory()->array_buffer_neutering_protector());
dependencies()->DependOnProtector(PropertyCellRef(
js_heap_broker(), factory()->array_buffer_neutering_protector()));
} else {
// Check if the {receiver}s buffer was neutered.
Node* buffer = effect = graph()->NewNode(
......@@ -7100,7 +7124,7 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
// Compute property access info for "exec" on {resolution}.
PropertyAccessInfo ai_exec;
AccessInfoFactory access_info_factory(dependencies(), js_heap_broker(),
AccessInfoFactory access_info_factory(js_heap_broker(), dependencies(),
native_context(), graph()->zone());
if (!access_info_factory.ComputePropertyAccessInfo(
MapHandles(regexp_maps.begin(), regexp_maps.end()),
......@@ -7112,13 +7136,14 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
Handle<Object> exec_on_proto = ai_exec.constant();
if (*exec_on_proto != *isolate()->regexp_exec_function()) return NoChange();
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
PropertyAccessBuilder access_builder(jsgraph(), js_heap_broker(),
dependencies());
// Add proper dependencies on the {regexp}s [[Prototype]]s.
Handle<JSObject> holder;
if (ai_exec.holder().ToHandle(&holder)) {
dependencies()->DependOnStablePrototypeChains(
native_context(), ai_exec.receiver_maps(), holder);
js_heap_broker(), native_context(), ai_exec.receiver_maps(), holder);
}
if (need_map_check) {
......
......@@ -139,7 +139,7 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
// Add a dependency on the {initial_map} to make sure that this code is
// deoptimized whenever the {initial_map} changes.
MapRef initial_map = original_constructor.DependOnInitialMap(dependencies());
MapRef initial_map = dependencies()->DependOnInitialMap(original_constructor);
// Force completion of inobject slack tracking before
// generating code to finalize the instance size.
......@@ -425,7 +425,7 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
// Add a dependency on the {initial_map} to make sure that this code is
// deoptimized whenever the {initial_map} changes.
MapRef initial_map = js_function.DependOnInitialMap(dependencies());
MapRef initial_map = dependencies()->DependOnInitialMap(js_function);
DCHECK(initial_map.instance_type() == JS_GENERATOR_OBJECT_TYPE ||
initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
......@@ -727,8 +727,8 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
// Add a dependency on the {initial_map} to make sure that this code is
// deoptimized whenever the {initial_map} changes.
Handle<Map> initial_map =
dependencies()->DependOnInitialMap(original_constructor);
MapRef initial_map = dependencies()->DependOnInitialMap(
JSFunctionRef(js_heap_broker(), original_constructor));
// Tells whether we are protected by either the {site} or a
// protector cell to do certain speculative optimizations.
......@@ -737,13 +737,16 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
// Check if we have a feedback {site} on the {node}.
if (!site.is_null()) {
ElementsKind elements_kind = site->GetElementsKind();
if (initial_map->elements_kind() != elements_kind) {
if (initial_map.elements_kind() != elements_kind) {
initial_map =
Map::AsElementsKind(isolate(), initial_map, elements_kind);
MapRef(js_heap_broker(),
Map::AsElementsKind(isolate(), initial_map.object<Map>(),
elements_kind));
}
can_inline_call = site->CanInlineCall();
pretenure = dependencies()->DependOnPretenureMode(site);
dependencies()->DependOnElementsKind(site);
auto site_ref = AllocationSiteRef(js_heap_broker(), site);
pretenure = dependencies()->DependOnPretenureMode(site_ref);
dependencies()->DependOnElementsKind(site_ref);
} else {
can_inline_call = isolate()->IsArrayConstructorIntact();
}
......@@ -751,31 +754,36 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
if (arity == 0) {
Node* length = jsgraph()->ZeroConstant();
int capacity = JSArray::kPreallocatedArrayElements;
return ReduceNewArray(node, length, capacity, initial_map, pretenure);
return ReduceNewArray(node, length, capacity, initial_map.object<Map>(),
pretenure);
} else if (arity == 1) {
Node* length = NodeProperties::GetValueInput(node, 2);
Type length_type = NodeProperties::GetType(length);
if (!length_type.Maybe(Type::Number())) {
// Handle the single argument case, where we know that the value
// cannot be a valid Array length.
ElementsKind elements_kind = initial_map->elements_kind();
ElementsKind elements_kind = initial_map.elements_kind();
elements_kind = GetMoreGeneralElementsKind(
elements_kind, IsHoleyElementsKind(elements_kind)
? HOLEY_ELEMENTS
: PACKED_ELEMENTS);
initial_map =
Map::AsElementsKind(isolate(), initial_map, elements_kind);
return ReduceNewArray(node, std::vector<Node*>{length}, initial_map,
pretenure);
MapRef(js_heap_broker(),
Map::AsElementsKind(isolate(), initial_map.object<Map>(),
elements_kind));
return ReduceNewArray(node, std::vector<Node*>{length},
initial_map.object<Map>(), pretenure);
}
if (length_type.Is(Type::SignedSmall()) && length_type.Min() >= 0 &&
length_type.Max() <= kElementLoopUnrollLimit &&
length_type.Min() == length_type.Max()) {
int capacity = static_cast<int>(length_type.Max());
return ReduceNewArray(node, length, capacity, initial_map, pretenure);
return ReduceNewArray(node, length, capacity,
initial_map.object<Map>(), pretenure);
}
if (length_type.Maybe(Type::UnsignedSmall()) && can_inline_call) {
return ReduceNewArray(node, length, initial_map, pretenure);
return ReduceNewArray(node, length, initial_map.object<Map>(),
pretenure);
}
} else if (arity <= JSArray::kInitialMaxFastElementArray) {
// Gather the values to store into the newly created array.
......@@ -799,7 +807,7 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
}
// Try to figure out the ideal elements kind statically.
ElementsKind elements_kind = initial_map->elements_kind();
ElementsKind elements_kind = initial_map.elements_kind();
if (values_all_smis) {
// Smis can be stored with any elements kind.
} else if (values_all_numbers) {
......@@ -821,9 +829,12 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
return NoChange();
}
initial_map =
Map::AsElementsKind(isolate(), initial_map, elements_kind);
MapRef(js_heap_broker(),
Map::AsElementsKind(isolate(), initial_map.object<Map>(),
elements_kind));
return ReduceNewArray(node, values, initial_map, pretenure);
return ReduceNewArray(node, values, initial_map.object<Map>(),
pretenure);
}
}
}
......@@ -1151,10 +1162,9 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
if (site.IsFastLiteral()) {
PretenureFlag pretenure = NOT_TENURED;
if (FLAG_allocation_site_pretenuring) {
pretenure = dependencies()->DependOnPretenureMode(
site.object<AllocationSite>());
pretenure = dependencies()->DependOnPretenureMode(site);
}
dependencies()->DependOnElementsKinds(site.object<AllocationSite>());
dependencies()->DependOnElementsKinds(site);
JSObjectRef boilerplate = site.boilerplate();
Node* value = effect =
AllocateFastLiteral(effect, control, boilerplate, pretenure);
......@@ -1176,8 +1186,10 @@ Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
Handle<Map> const initial_map(
native_context()->GetInitialJSArrayMap(site->GetElementsKind()),
isolate());
PretenureFlag const pretenure = dependencies()->DependOnPretenureMode(site);
dependencies()->DependOnElementsKind(site);
auto site_ref = AllocationSiteRef(js_heap_broker(), site);
PretenureFlag const pretenure =
dependencies()->DependOnPretenureMode(site_ref);
dependencies()->DependOnElementsKind(site_ref);
Node* length = jsgraph()->ZeroConstant();
return ReduceNewArray(node, length, 0, initial_map, pretenure);
}
......
......@@ -156,15 +156,6 @@ bool JSFunctionRef::IsConstructor() const {
return object<JSFunction>()->IsConstructor();
}
MapRef JSFunctionRef::DependOnInitialMap(
CompilationDependencies* dependencies) const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference allow_handle_dereference;
Handle<Map> initial_map =
dependencies->DependOnInitialMap(object<JSFunction>());
return MapRef(broker(), initial_map);
}
void JSFunctionRef::EnsureHasInitialMap() const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference allow_handle_dereference;
......@@ -175,13 +166,6 @@ void JSFunctionRef::EnsureHasInitialMap() const {
JSFunction::EnsureHasInitialMap(object<JSFunction>());
}
// TODO(neis): Remove.
void MapRef::DependOnStableMap(CompilationDependencies* dependencies) const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference allow_handle_dereference;
dependencies->DependOnStableMap(object<Map>());
}
SlackTrackingResult JSFunctionRef::FinishSlackTracking() const {
AllowHandleDereference allow_handle_dereference;
AllowHandleAllocation handle_allocation;
......@@ -265,6 +249,24 @@ JSObjectRef AllocationSiteRef::boilerplate() const {
return JSObjectRef(broker(), value);
}
ObjectRef AllocationSiteRef::nested_site() const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference handle_dereference;
Handle<Object> obj(object<AllocationSite>()->nested_site(),
broker()->isolate());
return ObjectRef(broker(), obj);
}
bool AllocationSiteRef::PointsToLiteral() const {
AllowHandleDereference handle_dereference;
return object<AllocationSite>()->PointsToLiteral();
}
ElementsKind AllocationSiteRef::GetElementsKind() const {
AllowHandleDereference handle_dereference;
return object<AllocationSite>()->GetElementsKind();
}
bool JSObjectRef::IsUnboxedDoubleField(FieldIndex index) const {
AllowHandleDereference handle_dereference;
return object<JSObject>()->IsUnboxedDoubleField(index);
......@@ -283,6 +285,11 @@ ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const {
broker()->isolate()));
}
ElementsKind JSObjectRef::GetElementsKind() {
AllowHandleDereference handle_dereference;
return object<JSObject>()->GetElementsKind();
}
FixedArrayBaseRef JSObjectRef::elements() const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference handle_dereference;
......@@ -405,6 +412,21 @@ void JSObjectRef::EnsureElementsTenured() {
}
}
ElementsKind MapRef::elements_kind() const {
AllowHandleDereference allow_handle_dereference;
return object<Map>()->elements_kind();
}
bool MapRef::is_deprecated() const {
AllowHandleDereference allow_handle_dereference;
return object<Map>()->is_deprecated();
}
bool MapRef::CanBeDeprecated() const {
AllowHandleDereference allow_handle_dereference;
return object<Map>()->CanBeDeprecated();
}
int MapRef::GetInObjectProperties() const {
AllowHandleDereference allow_handle_dereference;
return object<Map>()->GetInObjectProperties();
......@@ -491,6 +513,24 @@ bool MapRef::CanTransition() const {
return object<Map>()->CanTransition();
}
MapRef MapRef::FindFieldOwner(int descriptor) const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference allow_handle_dereference;
Handle<Map> owner(
object<Map>()->FindFieldOwner(broker()->isolate(), descriptor),
broker()->isolate());
return MapRef(broker(), owner);
}
FieldTypeRef MapRef::GetFieldType(int descriptor) const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference allow_handle_dereference;
Handle<FieldType> field_type(
object<Map>()->instance_descriptors()->GetFieldType(descriptor),
broker()->isolate());
return FieldTypeRef(broker(), field_type);
}
ElementsKind JSArrayRef::GetElementsKind() const {
AllowHandleDereference allow_handle_dereference;
return object<JSArray>()->GetElementsKind();
......@@ -791,6 +831,18 @@ CellRef ModuleRef::GetCell(int cell_index) {
broker()->isolate()));
}
ObjectRef PropertyCellRef::value() const {
AllowHandleAllocation allow_handle_allocation;
AllowHandleDereference allow_handle_dereference;
return ObjectRef(
broker(), handle(object<PropertyCell>()->value(), broker()->isolate()));
}
PropertyDetails PropertyCellRef::property_details() const {
AllowHandleDereference allow_handle_dereference;
return object<PropertyCell>()->property_details();
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -81,6 +81,7 @@ class HeapObjectType {
V(MutableHeapNumber) \
V(Name) \
V(NativeContext) \
V(PropertyCell) \
V(ScopeInfo) \
V(ScriptContextTable) \
V(SharedFunctionInfo) \
......@@ -130,6 +131,11 @@ class ObjectRef {
Handle<Object> object_;
};
class FieldTypeRef : public ObjectRef {
public:
using ObjectRef::ObjectRef;
};
class HeapObjectRef : public ObjectRef {
public:
using ObjectRef::ObjectRef;
......@@ -141,6 +147,14 @@ class HeapObjectRef : public ObjectRef {
bool IsExternalString() const;
};
class PropertyCellRef : public HeapObjectRef {
public:
using HeapObjectRef::HeapObjectRef;
ObjectRef value() const;
PropertyDetails property_details() const;
};
class JSObjectRef : public HeapObjectRef {
public:
using HeapObjectRef::HeapObjectRef;
......@@ -151,6 +165,7 @@ class JSObjectRef : public HeapObjectRef {
FixedArrayBaseRef elements() const;
void EnsureElementsTenured();
ElementsKind GetElementsKind();
};
struct SlackTrackingResult {
......@@ -170,9 +185,6 @@ class JSFunctionRef : public JSObjectRef {
bool IsConstructor() const;
bool has_initial_map() const;
MapRef initial_map() const;
MapRef DependOnInitialMap(CompilationDependencies* dependencies) const;
JSGlobalProxyRef global_proxy() const;
SlackTrackingResult FinishSlackTracking() const;
SharedFunctionInfoRef shared() const;
......@@ -267,6 +279,9 @@ class AllocationSiteRef : public HeapObjectRef {
JSObjectRef boilerplate() const;
PretenureFlag GetPretenureMode() const;
bool IsFastLiteral() const;
ObjectRef nested_site() const;
bool PointsToLiteral() const;
ElementsKind GetElementsKind() const;
};
class MapRef : public HeapObjectRef {
......@@ -281,18 +296,21 @@ class MapRef : public HeapObjectRef {
NameRef GetPropertyKey(int i) const;
FieldIndex GetFieldIndexFor(int i) const;
int GetInObjectPropertyOffset(int index) const;
ElementsKind elements_kind() const;
ObjectRef constructor_or_backpointer() const;
bool is_stable() const;
bool has_prototype_slot() const;
bool is_deprecated() const;
bool CanBeDeprecated() const;
bool CanTransition() const;
bool IsInobjectSlackTrackingInProgress() const;
MapRef FindFieldOwner(int descriptor) const;
bool is_dictionary_map() const;
bool IsJSArrayMap() const;
bool IsFixedCowArrayMap() const;
void DependOnStableMap(CompilationDependencies* dependencies) const;
// Concerning the underlying instance_descriptors:
FieldTypeRef GetFieldType(int descriptor) const;
};
class FixedArrayBaseRef : public HeapObjectRef {
......
......@@ -155,7 +155,7 @@ Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor(
// {function}s map is stable, i.e. we can use a code dependency
// to guard against [[Prototype]] changes of {function}.
if (function_map->is_stable() && function_prototype->IsConstructor()) {
dependencies()->DependOnStableMap(function_map);
dependencies()->DependOnStableMap(MapRef(js_heap_broker(), function_map));
Node* value = jsgraph()->Constant(function_prototype);
ReplaceWithValue(node, value);
return Replace(value);
......@@ -190,7 +190,7 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
// Compute property access info for @@hasInstance on {receiver}.
PropertyAccessInfo access_info;
AccessInfoFactory access_info_factory(dependencies(), js_heap_broker(),
AccessInfoFactory access_info_factory(js_heap_broker(), dependencies(),
native_context().object<Context>(),
graph()->zone());
if (!access_info_factory.ComputePropertyAccessInfo(
......@@ -199,7 +199,8 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
return NoChange();
}
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
PropertyAccessBuilder access_builder(jsgraph(), js_heap_broker(),
dependencies());
if (access_info.IsNotFound()) {
// If there's no @@hasInstance handler, the OrdinaryHasInstance operation
......@@ -209,8 +210,8 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
Handle<JSObject> holder;
if (access_info.holder().ToHandle(&holder)) {
dependencies()->DependOnStablePrototypeChains(
native_context().object<Context>(), access_info.receiver_maps(),
holder);
js_heap_broker(), native_context().object<Context>(),
access_info.receiver_maps(), holder);
}
// Check that {constructor} is actually {receiver}.
......@@ -235,8 +236,8 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
Handle<JSObject> holder;
if (access_info.holder().ToHandle(&holder)) {
dependencies()->DependOnStablePrototypeChains(
native_context().object<Context>(), access_info.receiver_maps(),
holder);
js_heap_broker(), native_context().object<Context>(),
access_info.receiver_maps(), holder);
} else {
holder = receiver;
}
......@@ -411,9 +412,10 @@ Reduction JSNativeContextSpecialization::ReduceJSOrdinaryHasInstance(
// depend on that for the prototype constant-folding below.
JSFunction::EnsureHasInitialMap(function);
Handle<Map> initial_map = dependencies()->DependOnInitialMap(function);
Node* prototype =
jsgraph()->Constant(handle(initial_map->prototype(), isolate()));
MapRef initial_map = dependencies()->DependOnInitialMap(
JSFunctionRef(js_heap_broker(), function));
Node* prototype = jsgraph()->Constant(
handle(initial_map.object<Map>()->prototype(), isolate()));
// Lower the {node} to JSHasInPrototypeChain.
NodeProperties::ReplaceValueInput(node, object, 0);
......@@ -483,7 +485,7 @@ Reduction JSNativeContextSpecialization::ReduceJSResolvePromise(Node* node) {
// Compute property access info for "then" on {resolution}.
PropertyAccessInfo access_info;
AccessInfoFactory access_info_factory(dependencies(), js_heap_broker(),
AccessInfoFactory access_info_factory(js_heap_broker(), dependencies(),
native_context().object<Context>(),
graph()->zone());
if (!access_info_factory.ComputePropertyAccessInfo(
......@@ -495,14 +497,15 @@ Reduction JSNativeContextSpecialization::ReduceJSResolvePromise(Node* node) {
// We can further optimize the case where {resolution}
// definitely doesn't have a "then" property.
if (!access_info.IsNotFound()) return NoChange();
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
PropertyAccessBuilder access_builder(jsgraph(), js_heap_broker(),
dependencies());
// Add proper dependencies on the {resolution}s [[Prototype]]s.
Handle<JSObject> holder;
if (access_info.holder().ToHandle(&holder)) {
dependencies()->DependOnStablePrototypeChains(
native_context().object<Context>(), access_info.receiver_maps(),
holder);
js_heap_broker(), native_context().object<Context>(),
access_info.receiver_maps(), holder);
}
// Simply fulfill the {promise} with the {resolution}.
......@@ -608,7 +611,8 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
// can be deleted or reconfigured to an accessor property).
if (property_details.cell_type() != PropertyCellType::kMutable ||
property_details.IsConfigurable()) {
dependencies()->DependOnGlobalProperty(property_cell);
dependencies()->DependOnGlobalProperty(
PropertyCellRef(js_heap_broker(), property_cell));
}
// Load from constant/undefined global property can be constant-folded.
......@@ -640,7 +644,8 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
// elimination if it's stable, i.e. the HeapObject wasn't
// mutated without the cell state being updated.
if (property_cell_value_map->is_stable()) {
dependencies()->DependOnStableMap(property_cell_value_map);
dependencies()->DependOnStableMap(
MapRef(js_heap_broker(), property_cell_value_map));
map = property_cell_value_map;
}
}
......@@ -662,7 +667,8 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
case PropertyCellType::kConstant: {
// Record a code dependency on the cell, and just deoptimize if the new
// value doesn't match the previous value stored inside the cell.
dependencies()->DependOnGlobalProperty(property_cell);
dependencies()->DependOnGlobalProperty(
PropertyCellRef(js_heap_broker(), property_cell));
Node* check =
graph()->NewNode(simplified()->ReferenceEqual(), value,
jsgraph()->Constant(property_cell_value));
......@@ -675,7 +681,8 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
// Record a code dependency on the cell, and just deoptimize if the new
// values' type doesn't match the type of the previous value in the
// cell.
dependencies()->DependOnGlobalProperty(property_cell);
dependencies()->DependOnGlobalProperty(
PropertyCellRef(js_heap_broker(), property_cell));
Type property_cell_value_type;
MachineRepresentation representation = MachineRepresentation::kTagged;
if (property_cell_value->IsHeapObject()) {
......@@ -684,7 +691,8 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
Handle<Map> property_cell_value_map(
Handle<HeapObject>::cast(property_cell_value)->map(), isolate());
DCHECK(property_cell_value_map->is_stable());
dependencies()->DependOnStableMap(property_cell_value_map);
dependencies()->DependOnStableMap(
MapRef(js_heap_broker(), property_cell_value_map));
// Check that the {value} is a HeapObject.
value = effect = graph()->NewNode(simplified()->CheckHeapObject(),
......@@ -715,7 +723,8 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
case PropertyCellType::kMutable: {
// Record a code dependency on the cell, and just deoptimize if the
// property ever becomes read-only.
dependencies()->DependOnGlobalProperty(property_cell);
dependencies()->DependOnGlobalProperty(
PropertyCellRef(js_heap_broker(), property_cell));
effect = graph()->NewNode(
simplified()->StoreField(ForPropertyCellValue(
MachineRepresentation::kTagged, Type::NonInternal(),
......@@ -817,7 +826,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
}
// Compute property access infos for the receiver maps.
AccessInfoFactory access_info_factory(dependencies(), js_heap_broker(),
AccessInfoFactory access_info_factory(js_heap_broker(), dependencies(),
native_context().object<Context>(),
graph()->zone());
ZoneVector<PropertyAccessInfo> access_infos(zone());
......@@ -845,7 +854,8 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
if_exceptions = &if_exception_nodes;
}
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
PropertyAccessBuilder access_builder(jsgraph(), js_heap_broker(),
dependencies());
// Check for the monomorphic cases.
if (access_infos.size() == 1) {
......@@ -1096,7 +1106,8 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
// {function} in order to be notified about changes to the
// "prototype" of {function}.
JSFunction::EnsureHasInitialMap(function);
dependencies()->DependOnInitialMap(function);
dependencies()->DependOnInitialMap(
JSFunctionRef(js_heap_broker(), function));
Handle<Object> prototype(function->prototype(), isolate());
Node* value = jsgraph()->Constant(prototype);
ReplaceWithValue(node, value);
......@@ -1181,7 +1192,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
} else {
// Retrieve the native context from the given {node}.
// Compute element access infos for the receiver maps.
AccessInfoFactory access_info_factory(dependencies(), js_heap_broker(),
AccessInfoFactory access_info_factory(js_heap_broker(), dependencies(),
native_context().object<Context>(),
graph()->zone());
ZoneVector<ElementAccessInfo> access_infos(zone());
......@@ -1230,12 +1241,14 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
// Install dependencies on the relevant prototype maps.
for (Handle<Map> prototype_map : prototype_maps) {
dependencies()->DependOnStableMap(prototype_map);
dependencies()->DependOnStableMap(
MapRef(js_heap_broker(), prototype_map));
}
}
// Ensure that {receiver} is a heap object.
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
PropertyAccessBuilder access_builder(jsgraph(), js_heap_broker(),
dependencies());
receiver = access_builder.BuildCheckHeapObject(receiver, &effect, control);
// Check for the monomorphic case.
......@@ -1798,11 +1811,12 @@ JSNativeContextSpecialization::BuildPropertyLoad(
PropertyAccessInfo const& access_info) {
// Determine actual holder and perform prototype chain checks.
Handle<JSObject> holder;
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
PropertyAccessBuilder access_builder(jsgraph(), js_heap_broker(),
dependencies());
if (access_info.holder().ToHandle(&holder)) {
dependencies()->DependOnStablePrototypeChains(
native_context().object<Context>(), access_info.receiver_maps(),
holder);
js_heap_broker(), native_context().object<Context>(),
access_info.receiver_maps(), holder);
}
// Generate the actual property access.
......@@ -1855,12 +1869,13 @@ JSNativeContextSpecialization::BuildPropertyStore(
PropertyAccessInfo const& access_info, AccessMode access_mode) {
// Determine actual holder and perform prototype chain checks.
Handle<JSObject> holder;
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
PropertyAccessBuilder access_builder(jsgraph(), js_heap_broker(),
dependencies());
if (access_info.holder().ToHandle(&holder)) {
DCHECK_NE(AccessMode::kStoreInLiteral, access_mode);
dependencies()->DependOnStablePrototypeChains(
native_context().object<Context>(), access_info.receiver_maps(),
holder);
js_heap_broker(), native_context().object<Context>(),
access_info.receiver_maps(), holder);
}
DCHECK(!access_info.IsNotFound());
......@@ -2083,7 +2098,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
Name::cast(nexus.GetFeedbackExtra()->ToStrongHeapObject()), isolate());
PropertyAccessInfo access_info;
AccessInfoFactory access_info_factory(dependencies(), js_heap_broker(),
AccessInfoFactory access_info_factory(js_heap_broker(), dependencies(),
native_context().object<Context>(),
graph()->zone());
if (!access_info_factory.ComputePropertyAccessInfo(
......@@ -2097,7 +2112,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
Node* control = NodeProperties::GetControlInput(node);
// Monomorphic property access.
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
PropertyAccessBuilder access_builder(jsgraph(), js_heap_broker(),
dependencies());
receiver = access_builder.BuildCheckHeapObject(receiver, &effect, control);
access_builder.BuildCheckMaps(receiver, &effect, control,
access_info.receiver_maps());
......@@ -2258,8 +2274,8 @@ JSNativeContextSpecialization::BuildElementAccess(
if (isolate()->IsArrayBufferNeuteringIntact()) {
// Add a code dependency so we are deoptimized in case an ArrayBuffer
// gets neutered.
dependencies()->DependOnProtector(
factory()->array_buffer_neutering_protector());
dependencies()->DependOnProtector(PropertyCellRef(
js_heap_broker(), factory()->array_buffer_neutering_protector()));
} else {
// Default to zero if the {receiver}s buffer was neutered.
Node* check = effect = graph()->NewNode(
......@@ -2661,7 +2677,8 @@ Node* JSNativeContextSpecialization::BuildIndexedStringLoad(
KeyedAccessLoadMode load_mode) {
if (load_mode == LOAD_IGNORE_OUT_OF_BOUNDS &&
isolate()->IsNoElementsProtectorIntact()) {
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
// Ensure that the {index} is a valid String length.
index = *effect = graph()->NewNode(
......@@ -2810,7 +2827,8 @@ bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
// Check if the array prototype chain is intact.
if (!isolate()->IsNoElementsProtectorIntact()) return false;
dependencies()->DependOnProtector(factory()->no_elements_protector());
dependencies()->DependOnProtector(
PropertyCellRef(js_heap_broker(), factory()->no_elements_protector()));
return true;
}
......
......@@ -135,7 +135,7 @@ class PipelineData {
javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_);
jsgraph_ = new (graph_zone_)
JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_);
js_heap_broker_ = new (graph_zone_) JSHeapBroker(isolate_);
js_heap_broker_ = new (codegen_zone_) JSHeapBroker(isolate_);
dependencies_ =
new (codegen_zone_) CompilationDependencies(isolate_, codegen_zone_);
}
......@@ -334,6 +334,7 @@ class PipelineData {
codegen_zone_scope_.Destroy();
codegen_zone_ = nullptr;
dependencies_ = nullptr;
js_heap_broker_ = nullptr;
frame_ = nullptr;
}
......@@ -447,7 +448,6 @@ class PipelineData {
JSGraph* jsgraph_ = nullptr;
MachineGraph* mcgraph_ = nullptr;
Schedule* schedule_ = nullptr;
JSHeapBroker* js_heap_broker_ = nullptr;
// All objects in the following group of fields are allocated in
// instruction_zone_. They are all set to nullptr when the instruction_zone_
......@@ -462,6 +462,7 @@ class PipelineData {
ZoneStats::Scope codegen_zone_scope_;
Zone* codegen_zone_;
CompilationDependencies* dependencies_ = nullptr;
JSHeapBroker* js_heap_broker_ = nullptr;
Frame* frame_ = nullptr;
// All objects in the following group of fields are allocated in
......
......@@ -136,7 +136,8 @@ void PropertyAccessBuilder::BuildCheckMaps(
if (receiver_map->is_stable()) {
for (Handle<Map> map : receiver_maps) {
if (map.is_identical_to(receiver_map)) {
dependencies()->DependOnStableMap(receiver_map);
dependencies()->DependOnStableMap(
MapRef(js_heap_broker(), receiver_map));
return;
}
}
......@@ -206,7 +207,9 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
// the field.
DCHECK(access_info.IsDataConstantField());
DCHECK(!it.is_dictionary_holder());
dependencies()->DependOnFieldType(&it);
MapRef map(js_heap_broker(),
handle(it.GetHolder<HeapObject>()->map(), isolate()));
dependencies()->DependOnFieldType(map, it.GetFieldDescriptorIndex());
}
return value;
}
......@@ -264,7 +267,7 @@ Node* PropertyAccessBuilder::BuildLoadDataField(
Handle<Map> field_map;
if (access_info.field_map().ToHandle(&field_map)) {
if (field_map->is_stable()) {
dependencies()->DependOnStableMap(field_map);
dependencies()->DependOnStableMap(MapRef(js_heap_broker(), field_map));
field_access.map = field_map;
}
}
......
......@@ -19,14 +19,18 @@ class CommonOperatorBuilder;
class CompilationDependencies;
class Graph;
class JSGraph;
class JSHeapBroker;
class Node;
class PropertyAccessInfo;
class SimplifiedOperatorBuilder;
class PropertyAccessBuilder {
public:
PropertyAccessBuilder(JSGraph* jsgraph, CompilationDependencies* dependencies)
: jsgraph_(jsgraph), dependencies_(dependencies) {}
PropertyAccessBuilder(JSGraph* jsgraph, const JSHeapBroker* js_heap_broker,
CompilationDependencies* dependencies)
: jsgraph_(jsgraph),
js_heap_broker_(js_heap_broker),
dependencies_(dependencies) {}
// Builds the appropriate string check if the maps are only string
// maps.
......@@ -50,6 +54,7 @@ class PropertyAccessBuilder {
private:
JSGraph* jsgraph() const { return jsgraph_; }
const JSHeapBroker* js_heap_broker() const { return js_heap_broker_; }
CompilationDependencies* dependencies() const { return dependencies_; }
Graph* graph() const;
Isolate* isolate() const;
......@@ -64,6 +69,7 @@ class PropertyAccessBuilder {
Node* ResolveHolder(PropertyAccessInfo const& access_info, Node* receiver);
JSGraph* jsgraph_;
const JSHeapBroker* js_heap_broker_;
CompilationDependencies* dependencies_;
};
......
......@@ -153,7 +153,7 @@ Reduction TypedOptimization::ReduceCheckMaps(Node* node) {
if (map_type.IsHeapConstant() &&
map_type.AsHeapConstant()->Ref().equals(*object_map)) {
if (object_map->CanTransition()) {
object_map->DependOnStableMap(dependencies());
dependencies()->DependOnStableMap(*object_map);
}
return Replace(effect);
}
......@@ -218,9 +218,7 @@ Reduction TypedOptimization::ReduceLoadField(Node* node) {
base::Optional<MapRef> object_map =
GetStableMapFromObjectType(js_heap_broker(), object_type);
if (object_map.has_value()) {
if (object_map->CanTransition()) {
object_map->DependOnStableMap(dependencies());
}
dependencies()->DependOnStableMap(*object_map);
Node* const value = jsgraph()->Constant(*object_map);
ReplaceWithValue(node, value);
return Replace(value);
......
......@@ -1456,7 +1456,7 @@ ACCESSORS(PropertyCell, name, Name, kNameOffset)
ACCESSORS(PropertyCell, value, Object, kValueOffset)
ACCESSORS(PropertyCell, property_details_raw, Object, kDetailsOffset)
PropertyDetails PropertyCell::property_details() {
PropertyDetails PropertyCell::property_details() const {
return PropertyDetails(Smi::cast(property_details_raw()));
}
......
......@@ -3909,7 +3909,7 @@ class PropertyCell : public HeapObject {
// property.
DECL_ACCESSORS(dependent_code, DependentCode)
inline PropertyDetails property_details();
inline PropertyDetails property_details() const;
inline void set_property_details(PropertyDetails details);
PropertyCellConstantType GetConstantType();
......
......@@ -11,6 +11,7 @@
#include "src/compilation-cache.h"
#include "src/compiler/compilation-dependencies.h"
#include "src/compiler/js-heap-broker.h"
#include "src/execution.h"
#include "src/field-type.h"
#include "src/global-handles.h"
......@@ -608,6 +609,7 @@ static void TestGeneralizeField(int detach_property_at_index,
bool expected_deprecation,
bool expected_field_type_dependency) {
Isolate* isolate = CcTest::i_isolate();
JSHeapBroker broker(isolate);
Handle<FieldType> any_type = FieldType::Any(isolate);
CHECK(detach_property_at_index >= -1 &&
......@@ -653,11 +655,12 @@ static void TestGeneralizeField(int detach_property_at_index,
}
// Create new maps by generalizing representation of propX field.
Handle<Map> field_owner(map->FindFieldOwner(isolate, property_index),
isolate);
CanonicalHandleScope canonical(isolate);
CompilationDependencies dependencies(isolate, &zone);
dependencies.DependOnFieldType(map, property_index);
dependencies.DependOnFieldType(MapRef(&broker, map), property_index);
Handle<Map> field_owner(map->FindFieldOwner(isolate, property_index),
isolate);
Handle<Map> new_map = Map::ReconfigureProperty(
isolate, map, property_index, kData, NONE, to.representation, to.type);
......@@ -986,6 +989,7 @@ TEST(GeneralizeFieldWithAccessorProperties) {
static void TestReconfigureDataFieldAttribute_GeneralizeField(
const CRFTData& from, const CRFTData& to, const CRFTData& expected) {
Isolate* isolate = CcTest::i_isolate();
JSHeapBroker broker(isolate);
Expectations expectations(isolate);
......@@ -1023,8 +1027,9 @@ static void TestReconfigureDataFieldAttribute_GeneralizeField(
CHECK(expectations2.Check(*map2));
Zone zone(isolate->allocator(), ZONE_NAME);
CanonicalHandleScope canonical(isolate);
CompilationDependencies dependencies(isolate, &zone);
dependencies.DependOnFieldType(map, kSplitProp);
dependencies.DependOnFieldType(MapRef(&broker, map), kSplitProp);
// Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which
// should generalize representations in |map1|.
......@@ -1068,6 +1073,7 @@ static void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
const CRFTData& from, const CRFTData& to, const CRFTData& expected,
bool expected_field_type_dependency = true) {
Isolate* isolate = CcTest::i_isolate();
JSHeapBroker broker(isolate);
Expectations expectations(isolate);
......@@ -1105,8 +1111,9 @@ static void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
CHECK(expectations2.Check(*map2));
Zone zone(isolate->allocator(), ZONE_NAME);
CanonicalHandleScope canonical(isolate);
CompilationDependencies dependencies(isolate, &zone);
dependencies.DependOnFieldType(map, kSplitProp);
dependencies.DependOnFieldType(MapRef(&broker, map), kSplitProp);
// Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which
// should generalize representations in |map1|.
......@@ -1746,6 +1753,7 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) {
static void TestReconfigureElementsKind_GeneralizeField(
const CRFTData& from, const CRFTData& to, const CRFTData& expected) {
Isolate* isolate = CcTest::i_isolate();
JSHeapBroker broker(isolate);
Expectations expectations(isolate, PACKED_SMI_ELEMENTS);
......@@ -1784,8 +1792,9 @@ static void TestReconfigureElementsKind_GeneralizeField(
CHECK(expectations2.Check(*map2));
Zone zone(isolate->allocator(), ZONE_NAME);
CanonicalHandleScope canonical(isolate);
CompilationDependencies dependencies(isolate, &zone);
dependencies.DependOnFieldType(map, kDiffProp);
dependencies.DependOnFieldType(MapRef(&broker, map), kDiffProp);
// Reconfigure elements kinds of |map2|, which should generalize
// representations in |map|.
......@@ -1839,6 +1848,7 @@ static void TestReconfigureElementsKind_GeneralizeField(
static void TestReconfigureElementsKind_GeneralizeFieldTrivial(
const CRFTData& from, const CRFTData& to, const CRFTData& expected) {
Isolate* isolate = CcTest::i_isolate();
JSHeapBroker broker(isolate);
Expectations expectations(isolate, PACKED_SMI_ELEMENTS);
......@@ -1877,8 +1887,9 @@ static void TestReconfigureElementsKind_GeneralizeFieldTrivial(
CHECK(expectations2.Check(*map2));
Zone zone(isolate->allocator(), ZONE_NAME);
CanonicalHandleScope canonical(isolate);
CompilationDependencies dependencies(isolate, &zone);
dependencies.DependOnFieldType(map, kDiffProp);
dependencies.DependOnFieldType(MapRef(&broker, map), kDiffProp);
// Reconfigure elements kinds of |map2|, which should generalize
// representations in |map|.
......
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