diff options
Diffstat (limited to 'deps/v8/src/compiler/compilation-dependencies.cc')
-rw-r--r-- | deps/v8/src/compiler/compilation-dependencies.cc | 132 |
1 files changed, 106 insertions, 26 deletions
diff --git a/deps/v8/src/compiler/compilation-dependencies.cc b/deps/v8/src/compiler/compilation-dependencies.cc index 4b3e684c51..efcce684b8 100644 --- a/deps/v8/src/compiler/compilation-dependencies.cc +++ b/deps/v8/src/compiler/compilation-dependencies.cc @@ -6,13 +6,15 @@ #include "src/handles-inl.h" #include "src/objects-inl.h" +#include "src/objects/allocation-site-inl.h" namespace v8 { namespace internal { namespace compiler { -CompilationDependencies::CompilationDependencies(Isolate* isolate, Zone* zone) - : zone_(zone), dependencies_(zone), isolate_(isolate) {} +CompilationDependencies::CompilationDependencies(JSHeapBroker* broker, + Zone* zone) + : zone_(zone), broker_(broker), dependencies_(zone) {} class CompilationDependencies::Dependency : public ZoneObject { public: @@ -164,24 +166,17 @@ class FieldTypeDependency final : public CompilationDependencies::Dependency { // TODO(neis): Once the concurrent compiler frontend is always-on, we no // longer need to explicitly store the type. FieldTypeDependency(const MapRef& owner, int descriptor, - const ObjectRef& type, PropertyConstness constness) - : owner_(owner), - descriptor_(descriptor), - type_(type), - constness_(constness) { + const ObjectRef& type) + : owner_(owner), descriptor_(descriptor), type_(type) { DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_))); DCHECK(type_.equals(owner_.GetFieldType(descriptor_))); - DCHECK_EQ(constness_, owner_.GetPropertyDetails(descriptor_).constness()); } bool IsValid() const override { DisallowHeapAllocation no_heap_allocation; Handle<Map> owner = owner_.object(); Handle<Object> type = type_.object(); - return *type == owner->instance_descriptors()->GetFieldType(descriptor_) && - constness_ == owner->instance_descriptors() - ->GetDetails(descriptor_) - .constness(); + return *type == owner->instance_descriptors()->GetFieldType(descriptor_); } void Install(const MaybeObjectHandle& code) override { @@ -194,7 +189,34 @@ class FieldTypeDependency final : public CompilationDependencies::Dependency { MapRef owner_; int descriptor_; ObjectRef type_; - PropertyConstness constness_; +}; + +class FieldConstnessDependency final + : public CompilationDependencies::Dependency { + public: + FieldConstnessDependency(const MapRef& owner, int descriptor) + : owner_(owner), descriptor_(descriptor) { + DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_))); + DCHECK_EQ(PropertyConstness::kConst, + owner_.GetPropertyDetails(descriptor_).constness()); + } + + bool IsValid() const override { + DisallowHeapAllocation no_heap_allocation; + Handle<Map> owner = owner_.object(); + return PropertyConstness::kConst == + owner->instance_descriptors()->GetDetails(descriptor_).constness(); + } + + void Install(const MaybeObjectHandle& code) override { + SLOW_DCHECK(IsValid()); + DependentCode::InstallDependency(owner_.isolate(), code, owner_.object(), + DependentCode::kFieldOwnerGroup); + } + + private: + MapRef owner_; + int descriptor_; }; class GlobalPropertyDependency final @@ -361,15 +383,37 @@ PretenureFlag CompilationDependencies::DependOnPretenureMode( return mode; } +PropertyConstness CompilationDependencies::DependOnFieldConstness( + const MapRef& map, int descriptor) { + MapRef owner = map.FindFieldOwner(descriptor); + PropertyConstness constness = + owner.GetPropertyDetails(descriptor).constness(); + if (constness == PropertyConstness::kMutable) return constness; + + // If the map can have fast elements transitions, then the field can be only + // considered constant if the map does not transition. + if (Map::CanHaveFastTransitionableElementsKind(map.instance_type())) { + // If the map can already transition away, let us report the field as + // mutable. + if (!map.is_stable()) { + return PropertyConstness::kMutable; + } + DependOnStableMap(map); + } + + DCHECK_EQ(constness, PropertyConstness::kConst); + dependencies_.push_front(new (zone_) + FieldConstnessDependency(owner, descriptor)); + return PropertyConstness::kConst; +} + void CompilationDependencies::DependOnFieldType(const MapRef& map, int descriptor) { MapRef owner = map.FindFieldOwner(descriptor); ObjectRef type = owner.GetFieldType(descriptor); - PropertyConstness constness = - owner.GetPropertyDetails(descriptor).constness(); DCHECK(type.equals(map.GetFieldType(descriptor))); - dependencies_.push_front( - new (zone_) FieldTypeDependency(owner, descriptor, type, constness)); + dependencies_.push_front(new (zone_) + FieldTypeDependency(owner, descriptor, type)); } void CompilationDependencies::DependOnGlobalProperty( @@ -380,8 +424,46 @@ void CompilationDependencies::DependOnGlobalProperty( GlobalPropertyDependency(cell, type, read_only)); } -void CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) { +bool CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) { + if (cell.value().AsSmi() != Isolate::kProtectorValid) return false; dependencies_.push_front(new (zone_) ProtectorDependency(cell)); + return true; +} + +bool CompilationDependencies::DependOnArrayBufferDetachingProtector() { + return DependOnProtector(PropertyCellRef( + broker_, + broker_->isolate()->factory()->array_buffer_detaching_protector())); +} + +bool CompilationDependencies::DependOnArrayIteratorProtector() { + return DependOnProtector(PropertyCellRef( + broker_, broker_->isolate()->factory()->array_iterator_protector())); +} + +bool CompilationDependencies::DependOnArraySpeciesProtector() { + return DependOnProtector(PropertyCellRef( + broker_, broker_->isolate()->factory()->array_species_protector())); +} + +bool CompilationDependencies::DependOnNoElementsProtector() { + return DependOnProtector(PropertyCellRef( + broker_, broker_->isolate()->factory()->no_elements_protector())); +} + +bool CompilationDependencies::DependOnPromiseHookProtector() { + return DependOnProtector(PropertyCellRef( + broker_, broker_->isolate()->factory()->promise_hook_protector())); +} + +bool CompilationDependencies::DependOnPromiseSpeciesProtector() { + return DependOnProtector(PropertyCellRef( + broker_, broker_->isolate()->factory()->promise_species_protector())); +} + +bool CompilationDependencies::DependOnPromiseThenProtector() { + return DependOnProtector(PropertyCellRef( + broker_, broker_->isolate()->factory()->promise_then_protector())); } void CompilationDependencies::DependOnElementsKind( @@ -431,7 +513,7 @@ bool CompilationDependencies::Commit(Handle<Code> code) { // these cases, because once the code gets executed it will do a stack check // that triggers its deoptimization. if (FLAG_stress_gc_during_compilation) { - isolate_->heap()->PreciseCollectAllGarbage( + broker_->isolate()->heap()->PreciseCollectAllGarbage( Heap::kNoGCFlags, GarbageCollectionReason::kTesting, kGCCallbackFlagForced); } @@ -447,8 +529,7 @@ bool CompilationDependencies::Commit(Handle<Code> code) { namespace { // This function expects to never see a JSProxy. -void DependOnStablePrototypeChain(JSHeapBroker* broker, - CompilationDependencies* deps, MapRef map, +void DependOnStablePrototypeChain(CompilationDependencies* deps, MapRef map, const JSObjectRef& last_prototype) { while (true) { map.SerializePrototype(); @@ -461,19 +542,18 @@ void DependOnStablePrototypeChain(JSHeapBroker* broker, } // namespace void CompilationDependencies::DependOnStablePrototypeChains( - JSHeapBroker* broker, std::vector<Handle<Map>> const& receiver_maps, - const JSObjectRef& holder) { + std::vector<Handle<Map>> const& receiver_maps, const JSObjectRef& holder) { // Determine actual holder and perform prototype chain checks. for (auto map : receiver_maps) { - MapRef receiver_map(broker, map); + MapRef receiver_map(broker_, map); if (receiver_map.IsPrimitiveMap()) { // Perform the implicit ToObject for primitives here. // Implemented according to ES6 section 7.3.2 GetV (V, P). base::Optional<JSFunctionRef> constructor = - broker->native_context().GetConstructorFunction(receiver_map); + broker_->native_context().GetConstructorFunction(receiver_map); if (constructor.has_value()) receiver_map = constructor->initial_map(); } - DependOnStablePrototypeChain(broker, this, receiver_map, holder); + DependOnStablePrototypeChain(this, receiver_map, holder); } } |