Commit 04bb707e authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Preprocess feedback for global accesses (partially)

Main changes:
- Rename ProcessedFeedback to ElementAccessFeedback and introduce a base class
  with the old name ProcessedFeedback.
- Introduce another kind of ProcessedFeedback, namely GlobalAccessFeedback for
  the LoadGlobal/StoreGlobal IC. It's either a PropertyCell or a script context
  slot.
- Produce such processed feedback in the serializer, when visiting LdaGlobal and
  similar bytecodes.
- Consume it, and disallow heap access, in JSNativeContextSpecialization's
  ReduceJSLoadGlobal and ReduceJSStoreGlobal (for --concurrent-inlining).

Minor changes:
- Introduce a FeedbackSource class (pair of FeedbackVector and FeedbackSlot)
  that is used as the key of the processed feedback hash table. We already have
  two similar classes, FeedbackNexus and VectorSlotPair, but both are unsuitable
  for technical reasons (e.g. FeedbackNexus construction accesses the heap).
  Eventually we should remove VectorSlotPair.
- Processed feedback is now returned as a pointer, which is nullptr if the
  original feedback wasn't interesting (e.g. megamorphic).

The title says "partially" because the CL doesn't yet take into account named
accesses where the receiver happens to be the global proxy.

Bug: v8:7790
Change-Id: I4404d98636b91a8f2d5667115944bae4773a4770
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1518184
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60240}
parent e8af602d
...@@ -260,38 +260,19 @@ bool AccessInfoFactory::ComputeElementAccessInfo( ...@@ -260,38 +260,19 @@ bool AccessInfoFactory::ComputeElementAccessInfo(
bool AccessInfoFactory::ComputeElementAccessInfos( bool AccessInfoFactory::ComputeElementAccessInfos(
FeedbackNexus nexus, MapHandles const& maps, AccessMode access_mode, FeedbackNexus nexus, MapHandles const& maps, AccessMode access_mode,
ZoneVector<ElementAccessInfo>* access_infos) const { ZoneVector<ElementAccessInfo>* access_infos) const {
ProcessedFeedback processed(broker()->zone()); ElementAccessFeedback const* processed;
if (FLAG_concurrent_inlining) { if (FLAG_concurrent_inlining) {
// TODO(neis): When concurrent inlining is ready,
// - change the printing below to not look into the heap,
// - remove the call to ProcessFeedbackMapsForElementAccess,
// - remove the Allow* scopes,
AllowCodeDependencyChange dependency_change_;
AllowHandleAllocation handle_allocation_;
AllowHandleDereference handle_dereference_;
AllowHeapAllocation heap_allocation_;
// We have already processed the feedback for this nexus during
// serialization. Use that data! We still process the incoming {maps} (even
// though we don't use them) so that we can print a comparison.
ProcessFeedbackMapsForElementAccess(broker(), maps, &processed);
ProcessedFeedback const& preprocessed = broker()->GetFeedback(nexus);
TRACE_BROKER(broker(), TRACE_BROKER(broker(),
"ComputeElementAccessInfos: using preprocessed feedback " "ComputeElementAccessInfos: using preprocessed feedback "
<< "(slot " << nexus.slot() << " of " << "(slot " << nexus.slot() << " of "
<< Brief(*nexus.vector_handle()) << "; " << "feedback vector handle "
<< preprocessed.receiver_maps.size() << "/" << nexus.vector_handle().address() << ").\n");
<< preprocessed.transitions.size() << " vs " processed = broker()->GetElementAccessFeedback(FeedbackSource(nexus));
<< processed.receiver_maps.size() << "/"
<< processed.transitions.size() << ").\n");
processed.receiver_maps = preprocessed.receiver_maps;
processed.transitions = preprocessed.transitions;
} else { } else {
ProcessFeedbackMapsForElementAccess(broker(), maps, &processed); processed = broker()->ProcessFeedbackMapsForElementAccess(maps);
} }
if (processed.receiver_maps.empty()) return false; if (processed == nullptr) return false;
if (access_mode == AccessMode::kLoad || access_mode == AccessMode::kHas) { if (access_mode == AccessMode::kLoad || access_mode == AccessMode::kHas) {
// For polymorphic loads of similar elements kinds (i.e. all tagged or all // For polymorphic loads of similar elements kinds (i.e. all tagged or all
...@@ -299,13 +280,13 @@ bool AccessInfoFactory::ComputeElementAccessInfos( ...@@ -299,13 +280,13 @@ bool AccessInfoFactory::ComputeElementAccessInfos(
// much faster than transitioning the elements to the worst case, trading a // much faster than transitioning the elements to the worst case, trading a
// TransitionElementsKind for a CheckMaps, avoiding mutation of the array. // TransitionElementsKind for a CheckMaps, avoiding mutation of the array.
ElementAccessInfo access_info; ElementAccessInfo access_info;
if (ConsolidateElementLoad(processed, &access_info)) { if (ConsolidateElementLoad(*processed, &access_info)) {
access_infos->push_back(access_info); access_infos->push_back(access_info);
return true; return true;
} }
} }
for (Handle<Map> receiver_map : processed.receiver_maps) { for (Handle<Map> receiver_map : processed->receiver_maps) {
// Compute the element access information. // Compute the element access information.
ElementAccessInfo access_info; ElementAccessInfo access_info;
if (!ComputeElementAccessInfo(receiver_map, access_mode, &access_info)) { if (!ComputeElementAccessInfo(receiver_map, access_mode, &access_info)) {
...@@ -313,7 +294,7 @@ bool AccessInfoFactory::ComputeElementAccessInfos( ...@@ -313,7 +294,7 @@ bool AccessInfoFactory::ComputeElementAccessInfos(
} }
// Collect the possible transitions for the {receiver_map}. // Collect the possible transitions for the {receiver_map}.
for (auto transition : processed.transitions) { for (auto transition : processed->transitions) {
if (transition.second.equals(receiver_map)) { if (transition.second.equals(receiver_map)) {
access_info.AddTransitionSource(transition.first); access_info.AddTransitionSource(transition.first);
} }
...@@ -624,8 +605,9 @@ Maybe<ElementsKind> GeneralizeElementsKind(ElementsKind this_kind, ...@@ -624,8 +605,9 @@ Maybe<ElementsKind> GeneralizeElementsKind(ElementsKind this_kind,
} // namespace } // namespace
bool AccessInfoFactory::ConsolidateElementLoad( bool AccessInfoFactory::ConsolidateElementLoad(
ProcessedFeedback const& processed, ElementAccessInfo* access_info) const { ElementAccessFeedback const& processed,
ProcessedFeedback::MapIterator it = processed.all_maps(broker()); ElementAccessInfo* access_info) const {
ElementAccessFeedback::MapIterator it = processed.all_maps(broker());
MapRef first_map = it.current(); MapRef first_map = it.current();
InstanceType instance_type = first_map.instance_type(); InstanceType instance_type = first_map.instance_type();
ElementsKind elements_kind = first_map.elements_kind(); ElementsKind elements_kind = first_map.elements_kind();
......
...@@ -25,9 +25,9 @@ namespace compiler { ...@@ -25,9 +25,9 @@ namespace compiler {
// Forward declarations. // Forward declarations.
class CompilationDependencies; class CompilationDependencies;
class ElementAccessFeedback;
class Type; class Type;
class TypeCache; class TypeCache;
struct ProcessedFeedback;
// Whether we are loading a property or storing to a property. // Whether we are loading a property or storing to a property.
// For a store during literal creation, do not walk up the prototype chain. // For a store during literal creation, do not walk up the prototype chain.
...@@ -166,7 +166,7 @@ class AccessInfoFactory final { ...@@ -166,7 +166,7 @@ class AccessInfoFactory final {
ZoneVector<PropertyAccessInfo>* access_infos) const; ZoneVector<PropertyAccessInfo>* access_infos) const;
private: private:
bool ConsolidateElementLoad(ProcessedFeedback const& processed, bool ConsolidateElementLoad(ElementAccessFeedback const& processed,
ElementAccessInfo* access_info) const; ElementAccessInfo* access_info) const;
bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name, bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
PropertyAccessInfo* access_info) const; PropertyAccessInfo* access_info) const;
......
This diff is collapsed.
...@@ -21,6 +21,7 @@ namespace v8 { ...@@ -21,6 +21,7 @@ namespace v8 {
namespace internal { namespace internal {
class BytecodeArray; class BytecodeArray;
class VectorSlotPair;
class FixedDoubleArray; class FixedDoubleArray;
class HeapNumber; class HeapNumber;
class InternalizedString; class InternalizedString;
...@@ -186,6 +187,8 @@ class PropertyCellRef : public HeapObjectRef { ...@@ -186,6 +187,8 @@ class PropertyCellRef : public HeapObjectRef {
Handle<PropertyCell> object() const; Handle<PropertyCell> object() const;
PropertyDetails property_details() const; PropertyDetails property_details() const;
void Serialize();
ObjectRef value() const; ObjectRef value() const;
}; };
...@@ -622,8 +625,40 @@ class InternalizedStringRef : public StringRef { ...@@ -622,8 +625,40 @@ class InternalizedStringRef : public StringRef {
static const uint32_t kNotAnArrayIndex = -1; // 2^32-1 is not a valid index. static const uint32_t kNotAnArrayIndex = -1; // 2^32-1 is not a valid index.
}; };
struct ProcessedFeedback { class ProcessedFeedback : public ZoneObject {
explicit ProcessedFeedback(Zone* zone); public:
enum Kind { kElementAccess, kGlobalAccess };
Kind kind() const { return kind_; }
protected:
explicit ProcessedFeedback(Kind kind) : kind_(kind) {}
private:
Kind const kind_;
};
class GlobalAccessFeedback : public ProcessedFeedback {
public:
explicit GlobalAccessFeedback(PropertyCellRef cell);
GlobalAccessFeedback(ContextRef script_context, int slot_index,
bool immutable);
bool IsPropertyCell() const;
PropertyCellRef property_cell() const;
bool IsScriptContextSlot() const { return !IsPropertyCell(); }
ContextRef script_context() const;
int slot_index() const;
bool immutable() const;
private:
ObjectRef const cell_or_context_;
int const index_and_immutable_;
};
class ElementAccessFeedback : public ProcessedFeedback {
public:
explicit ElementAccessFeedback(Zone* zone);
// No transition sources appear in {receiver_maps}. // No transition sources appear in {receiver_maps}.
// All transition targets appear in {receiver_maps}. // All transition targets appear in {receiver_maps}.
...@@ -637,12 +672,12 @@ struct ProcessedFeedback { ...@@ -637,12 +672,12 @@ struct ProcessedFeedback {
MapRef current() const; MapRef current() const;
private: private:
friend struct ProcessedFeedback; friend class ElementAccessFeedback;
explicit MapIterator(ProcessedFeedback const& processed, explicit MapIterator(ElementAccessFeedback const& processed,
JSHeapBroker* broker); JSHeapBroker* broker);
ProcessedFeedback const& processed_; ElementAccessFeedback const& processed_;
JSHeapBroker* const broker_; JSHeapBroker* const broker_;
size_t index_ = 0; size_t index_ = 0;
}; };
...@@ -651,6 +686,29 @@ struct ProcessedFeedback { ...@@ -651,6 +686,29 @@ struct ProcessedFeedback {
MapIterator all_maps(JSHeapBroker* broker) const; MapIterator all_maps(JSHeapBroker* broker) const;
}; };
struct FeedbackSource {
FeedbackSource(Handle<FeedbackVector> vector_, FeedbackSlot slot_)
: vector(vector_), slot(slot_) {}
explicit FeedbackSource(FeedbackNexus const& nexus);
explicit FeedbackSource(VectorSlotPair const& pair);
Handle<FeedbackVector> const vector;
FeedbackSlot const slot;
struct Hash {
size_t operator()(FeedbackSource const& source) const {
return base::hash_combine(source.vector.address(), source.slot);
}
};
struct Equal {
bool operator()(FeedbackSource const& lhs,
FeedbackSource const& rhs) const {
return lhs.vector.equals(rhs.vector) && lhs.slot == rhs.slot;
}
};
};
class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) { class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
public: public:
JSHeapBroker(Isolate* isolate, Zone* broker_zone); JSHeapBroker(Isolate* isolate, Zone* broker_zone);
...@@ -681,9 +739,24 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -681,9 +739,24 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
// %ObjectPrototype%. // %ObjectPrototype%.
bool IsArrayOrObjectPrototype(const JSObjectRef& object) const; bool IsArrayOrObjectPrototype(const JSObjectRef& object) const;
ProcessedFeedback& CreateEmptyFeedback(FeedbackNexus const& nexus); bool HasFeedback(FeedbackSource const& source) const;
bool HasFeedback(FeedbackNexus const& nexus) const; // The processed {feedback} can be {nullptr}, indicating that the original
ProcessedFeedback& GetFeedback(FeedbackNexus const& nexus); // feedback didn't contain information relevant for Turbofan.
void SetFeedback(FeedbackSource const& source,
ProcessedFeedback const* feedback);
ProcessedFeedback const* GetFeedback(FeedbackSource const& source) const;
// Convenience wrappers around GetFeedback.
ElementAccessFeedback const* GetElementAccessFeedback(
FeedbackSource const& source) const;
GlobalAccessFeedback const* GetGlobalAccessFeedback(
FeedbackSource const& source) const;
// TODO(neis): Move these into serializer when we're always in the background.
ElementAccessFeedback const* ProcessFeedbackMapsForElementAccess(
MapHandles const& maps);
GlobalAccessFeedback const* ProcessFeedbackForGlobalAccess(
FeedbackSource const& source);
std::ostream& Trace(); std::ostream& Trace();
void IncrementTracingIndentation(); void IncrementTracingIndentation();
...@@ -697,18 +770,6 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -697,18 +770,6 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
void SerializeShareableObjects(); void SerializeShareableObjects();
void CollectArrayAndObjectPrototypes(); void CollectArrayAndObjectPrototypes();
struct FeedbackNexusHash {
size_t operator()(FeedbackNexus const& nexus) const {
return base::hash_combine(nexus.vector_handle().address(), nexus.slot());
}
};
struct FeedbackNexusEqual {
bool operator()(FeedbackNexus const& lhs, FeedbackNexus const& rhs) const {
return lhs.vector_handle().equals(rhs.vector_handle()) &&
lhs.slot() == rhs.slot();
}
};
Isolate* const isolate_; Isolate* const isolate_;
Zone* const broker_zone_; Zone* const broker_zone_;
Zone* current_zone_; Zone* current_zone_;
...@@ -721,8 +782,8 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -721,8 +782,8 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
StdoutStream trace_out_; StdoutStream trace_out_;
unsigned trace_indentation_ = 0; unsigned trace_indentation_ = 0;
PerIsolateCompilerCache* compiler_cache_; PerIsolateCompilerCache* compiler_cache_;
ZoneUnorderedMap<FeedbackNexus, ProcessedFeedback, FeedbackNexusHash, ZoneUnorderedMap<FeedbackSource, ProcessedFeedback const*,
FeedbackNexusEqual> FeedbackSource::Hash, FeedbackSource::Equal>
feedback_; feedback_;
static const size_t kMinimalRefsBucketCount = 8; // must be power of 2 static const size_t kMinimalRefsBucketCount = 8; // must be power of 2
...@@ -743,9 +804,6 @@ Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker, ...@@ -743,9 +804,6 @@ Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker,
// Miscellaneous definitions that should be moved elsewhere once concurrent // Miscellaneous definitions that should be moved elsewhere once concurrent
// compilation is finished. // compilation is finished.
bool CanInlineElementAccess(MapRef const& map); bool CanInlineElementAccess(MapRef const& map);
void ProcessFeedbackMapsForElementAccess(JSHeapBroker* broker,
MapHandles const& maps,
ProcessedFeedback* processed);
#define TRACE_BROKER(broker, x) \ #define TRACE_BROKER(broker, x) \
do { \ do { \
......
...@@ -116,7 +116,8 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -116,7 +116,8 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
Node* index = nullptr); Node* index = nullptr);
Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value, Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
Handle<Name> name, AccessMode access_mode, Handle<Name> name, AccessMode access_mode,
Node* index, Handle<PropertyCell> property_cell); Node* index,
PropertyCellRef const& property_cell);
Reduction ReduceKeyedLoadFromHeapConstant(Node* node, Node* index, Reduction ReduceKeyedLoadFromHeapConstant(Node* node, Node* index,
FeedbackNexus const& nexus, FeedbackNexus const& nexus,
AccessMode access_mode, AccessMode access_mode,
......
...@@ -683,13 +683,59 @@ void SerializerForBackgroundCompilation::VisitConstructWithSpread( ...@@ -683,13 +683,59 @@ void SerializerForBackgroundCompilation::VisitConstructWithSpread(
ProcessCallOrConstruct(callee, new_target, arguments, slot, true); ProcessCallOrConstruct(callee, new_target, arguments, slot, true);
} }
void SerializerForBackgroundCompilation::ProcessFeedbackForGlobalAccess(
FeedbackSlot slot) {
if (slot.IsInvalid()) return;
if (environment()->function().feedback_vector.is_null()) return;
FeedbackSource source(environment()->function().feedback_vector, slot);
if (!broker()->HasFeedback(source)) {
broker()->SetFeedback(source,
broker()->ProcessFeedbackForGlobalAccess(source));
}
// TODO(neis, mvstanton): In the case of an immutable script context slot, we
// must also serialize that slot such that ContextRef::get can retrieve the
// value.
}
void SerializerForBackgroundCompilation::VisitLdaGlobal(
BytecodeArrayIterator* iterator) {
FeedbackSlot slot = iterator->GetSlotOperand(1);
ProcessFeedbackForGlobalAccess(slot);
// TODO(neis, mvstanton): In the case of an immutable script context slot, add
// the value as constant hint here and below
environment()->accumulator_hints().Clear();
}
void SerializerForBackgroundCompilation::VisitLdaGlobalInsideTypeof(
BytecodeArrayIterator* iterator) {
VisitLdaGlobal(iterator);
}
void SerializerForBackgroundCompilation::VisitLdaLookupGlobalSlot(
BytecodeArrayIterator* iterator) {
VisitLdaGlobal(iterator);
}
void SerializerForBackgroundCompilation::VisitLdaLookupGlobalSlotInsideTypeof(
BytecodeArrayIterator* iterator) {
VisitLdaGlobal(iterator);
}
void SerializerForBackgroundCompilation::VisitStaGlobal(
BytecodeArrayIterator* iterator) {
FeedbackSlot slot = iterator->GetSlotOperand(1);
ProcessFeedbackForGlobalAccess(slot);
}
// Note: We never use the same feeedback slot for multiple access modes.
void SerializerForBackgroundCompilation::ProcessFeedbackForKeyedPropertyAccess( void SerializerForBackgroundCompilation::ProcessFeedbackForKeyedPropertyAccess(
FeedbackSlot slot, AccessMode mode) { FeedbackSlot slot, AccessMode mode) {
if (slot.IsInvalid()) return; if (slot.IsInvalid()) return;
if (environment()->function().feedback_vector.is_null()) return; if (environment()->function().feedback_vector.is_null()) return;
FeedbackNexus nexus(environment()->function().feedback_vector, slot); FeedbackNexus nexus(environment()->function().feedback_vector, slot);
if (broker()->HasFeedback(nexus)) return; FeedbackSource source(nexus);
if (broker()->HasFeedback(source)) return;
if (nexus.ic_state() == MEGAMORPHIC) return; if (nexus.ic_state() == MEGAMORPHIC) return;
...@@ -702,10 +748,12 @@ void SerializerForBackgroundCompilation::ProcessFeedbackForKeyedPropertyAccess( ...@@ -702,10 +748,12 @@ void SerializerForBackgroundCompilation::ProcessFeedbackForKeyedPropertyAccess(
MapHandles maps; MapHandles maps;
nexus.ExtractMaps(&maps); nexus.ExtractMaps(&maps);
ProcessedFeedback& processed = broker()->CreateEmptyFeedback(nexus); ElementAccessFeedback const* processed =
ProcessFeedbackMapsForElementAccess(broker(), maps, &processed); broker()->ProcessFeedbackMapsForElementAccess(maps);
broker()->SetFeedback(source, processed);
if (processed == nullptr) return;
for (ProcessedFeedback::MapIterator it = processed.all_maps(broker()); for (ElementAccessFeedback::MapIterator it = processed->all_maps(broker());
!it.done(); it.advance()) { !it.done(); it.advance()) {
switch (mode) { switch (mode) {
case AccessMode::kHas: case AccessMode::kHas:
......
...@@ -55,8 +55,6 @@ namespace compiler { ...@@ -55,8 +55,6 @@ namespace compiler {
V(CreateUnmappedArguments) \ V(CreateUnmappedArguments) \
V(LdaContextSlot) \ V(LdaContextSlot) \
V(LdaCurrentContextSlot) \ V(LdaCurrentContextSlot) \
V(LdaGlobal) \
V(LdaGlobalInsideTypeof) \
V(LdaImmutableContextSlot) \ V(LdaImmutableContextSlot) \
V(LdaImmutableCurrentContextSlot) \ V(LdaImmutableCurrentContextSlot) \
V(LdaNamedProperty) \ V(LdaNamedProperty) \
...@@ -104,42 +102,47 @@ namespace compiler { ...@@ -104,42 +102,47 @@ namespace compiler {
V(ThrowSuperNotCalledIfHole) \ V(ThrowSuperNotCalledIfHole) \
V(ThrowSuperAlreadyCalledIfNotHole) V(ThrowSuperAlreadyCalledIfNotHole)
#define SUPPORTED_BYTECODE_LIST(V) \ #define SUPPORTED_BYTECODE_LIST(V) \
V(CallAnyReceiver) \ V(CallAnyReceiver) \
V(CallNoFeedback) \ V(CallNoFeedback) \
V(CallProperty) \ V(CallProperty) \
V(CallProperty0) \ V(CallProperty0) \
V(CallProperty1) \ V(CallProperty1) \
V(CallProperty2) \ V(CallProperty2) \
V(CallUndefinedReceiver) \ V(CallUndefinedReceiver) \
V(CallUndefinedReceiver0) \ V(CallUndefinedReceiver0) \
V(CallUndefinedReceiver1) \ V(CallUndefinedReceiver1) \
V(CallUndefinedReceiver2) \ V(CallUndefinedReceiver2) \
V(CallWithSpread) \ V(CallWithSpread) \
V(Construct) \ V(Construct) \
V(ConstructWithSpread) \ V(ConstructWithSpread) \
V(CreateClosure) \ V(CreateClosure) \
V(ExtraWide) \ V(ExtraWide) \
V(Illegal) \ V(Illegal) \
V(LdaConstant) \ V(LdaConstant) \
V(LdaKeyedProperty) \ V(LdaGlobal) \
V(LdaNull) \ V(LdaGlobalInsideTypeof) \
V(Ldar) \ V(LdaKeyedProperty) \
V(LdaSmi) \ V(LdaLookupGlobalSlot) \
V(LdaUndefined) \ V(LdaLookupGlobalSlotInsideTypeof) \
V(LdaZero) \ V(LdaNull) \
V(Mov) \ V(Ldar) \
V(Return) \ V(LdaSmi) \
V(StackCheck) \ V(LdaUndefined) \
V(StaInArrayLiteral) \ V(LdaZero) \
V(StaKeyedProperty) \ V(Mov) \
V(Star) \ V(Return) \
V(TestIn) \ V(StackCheck) \
V(Wide) \ V(StaGlobal) \
CLEAR_ENVIRONMENT_LIST(V) \ V(StaInArrayLiteral) \
CLEAR_ACCUMULATOR_LIST(V) \ V(StaKeyedProperty) \
CONDITIONAL_JUMPS_LIST(V) \ V(Star) \
UNCONDITIONAL_JUMPS_LIST(V) \ V(TestIn) \
V(Wide) \
CLEAR_ENVIRONMENT_LIST(V) \
CLEAR_ACCUMULATOR_LIST(V) \
CONDITIONAL_JUMPS_LIST(V) \
UNCONDITIONAL_JUMPS_LIST(V) \
INGORED_BYTECODE_LIST(V) INGORED_BYTECODE_LIST(V)
class JSHeapBroker; class JSHeapBroker;
...@@ -245,6 +248,7 @@ class SerializerForBackgroundCompilation { ...@@ -245,6 +248,7 @@ class SerializerForBackgroundCompilation {
base::Optional<Hints> new_target, base::Optional<Hints> new_target,
const HintsVector& arguments, bool with_spread); const HintsVector& arguments, bool with_spread);
void ProcessFeedbackForGlobalAccess(FeedbackSlot slot);
void ProcessFeedbackForKeyedPropertyAccess(FeedbackSlot slot, void ProcessFeedbackForKeyedPropertyAccess(FeedbackSlot slot,
AccessMode mode); AccessMode mode);
......
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