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