Commit 942193f0 authored by Mike Stanton's avatar Mike Stanton Committed by Commit Bot

[TurboFan] Prefer ProcessedFeedback over raw serialized Vector reads

Almost everywhere, we use the ProcessedFeedback abstraction to
query feedback in the compiler. The remaining exception is in handling
RegExp, Object and Array literals. By bringing this in line with
other feedback queries, we no longer need to serialize all feedback
vector slots (possibly wasteful of memory), and offer a uniform way
to pick up feedback everywhere.

Bug: v8:7790, v8:9396
Change-Id: Ice42587595fe30bebfbd7835d2b2e9e49601c92e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1807358
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64016}
parent f8a08223
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "src/objects/literal-objects-inl.h" #include "src/objects/literal-objects-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/smi.h" #include "src/objects/smi.h"
#include "src/objects/template-objects-inl.h" #include "src/objects/template-objects.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -2090,12 +2090,13 @@ void BytecodeGraphBuilder::VisitCloneObject() { ...@@ -2090,12 +2090,13 @@ void BytecodeGraphBuilder::VisitCloneObject() {
void BytecodeGraphBuilder::VisitGetTemplateObject() { void BytecodeGraphBuilder::VisitGetTemplateObject() {
DisallowHeapAccessIf no_heap_access(FLAG_concurrent_inlining); DisallowHeapAccessIf no_heap_access(FLAG_concurrent_inlining);
FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1); FeedbackSource source =
ObjectRef description( CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
TemplateObjectDescriptionRef description(
broker(), bytecode_iterator().GetConstantForIndexOperand(0, isolate())); broker(), bytecode_iterator().GetConstantForIndexOperand(0, isolate()));
JSArrayRef template_object = Node* template_object = NewNode(javascript()->GetTemplateObject(
shared_info().GetTemplateObject(description, feedback_vector(), slot); description.object(), shared_info().object(), source));
environment()->BindAccumulator(jsgraph()->Constant(template_object)); environment()->BindAccumulator(template_object);
} }
Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters( Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
......
...@@ -29,7 +29,6 @@ class NativeContext; ...@@ -29,7 +29,6 @@ class NativeContext;
class ScriptContextTable; class ScriptContextTable;
namespace compiler { namespace compiler {
// 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.
enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas }; enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas };
...@@ -95,10 +94,12 @@ enum class OddballType : uint8_t { ...@@ -95,10 +94,12 @@ enum class OddballType : uint8_t {
V(PropertyCell) \ V(PropertyCell) \
V(SharedFunctionInfo) \ V(SharedFunctionInfo) \
V(SourceTextModule) \ V(SourceTextModule) \
V(TemplateObjectDescription) \
/* Subtypes of Object */ \ /* Subtypes of Object */ \
V(HeapObject) V(HeapObject)
class CompilationDependencies; class CompilationDependencies;
struct FeedbackSource;
class JSHeapBroker; class JSHeapBroker;
class ObjectData; class ObjectData;
class PerIsolateCompilerCache; class PerIsolateCompilerCache;
...@@ -342,6 +343,8 @@ class JSRegExpRef : public JSObjectRef { ...@@ -342,6 +343,8 @@ class JSRegExpRef : public JSObjectRef {
ObjectRef source() const; ObjectRef source() const;
ObjectRef flags() const; ObjectRef flags() const;
ObjectRef last_index() const; ObjectRef last_index() const;
void SerializeAsRegExpBoilerplate();
}; };
class HeapNumberRef : public HeapObjectRef { class HeapNumberRef : public HeapObjectRef {
...@@ -494,7 +497,6 @@ class FeedbackVectorRef : public HeapObjectRef { ...@@ -494,7 +497,6 @@ class FeedbackVectorRef : public HeapObjectRef {
double invocation_count() const; double invocation_count() const;
void Serialize(); void Serialize();
ObjectRef get(FeedbackSlot slot) const;
FeedbackCellRef GetClosureFeedbackCell(int index) const; FeedbackCellRef GetClosureFeedbackCell(int index) const;
}; };
...@@ -533,6 +535,9 @@ class AllocationSiteRef : public HeapObjectRef { ...@@ -533,6 +535,9 @@ class AllocationSiteRef : public HeapObjectRef {
// //
// If PointsToLiteral() is false, then IsFastLiteral() is also false. // If PointsToLiteral() is false, then IsFastLiteral() is also false.
bool IsFastLiteral() const; bool IsFastLiteral() const;
void SerializeBoilerplate();
// We only serialize boilerplate if IsFastLiteral is true. // We only serialize boilerplate if IsFastLiteral is true.
base::Optional<JSObjectRef> boilerplate() const; base::Optional<JSObjectRef> boilerplate() const;
...@@ -789,7 +794,7 @@ class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef { ...@@ -789,7 +794,7 @@ class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef {
// wraps the retrieval of the template object and creates it if // wraps the retrieval of the template object and creates it if
// necessary. // necessary.
JSArrayRef GetTemplateObject( JSArrayRef GetTemplateObject(
ObjectRef description, FeedbackVectorRef vector, FeedbackSlot slot, TemplateObjectDescriptionRef description, FeedbackSource const& source,
SerializationPolicy policy = SerializationPolicy::kAssumeSerialized); SerializationPolicy policy = SerializationPolicy::kAssumeSerialized);
void SerializeFunctionTemplateInfo(); void SerializeFunctionTemplateInfo();
...@@ -843,6 +848,13 @@ class SourceTextModuleRef : public HeapObjectRef { ...@@ -843,6 +848,13 @@ class SourceTextModuleRef : public HeapObjectRef {
base::Optional<CellRef> GetCell(int cell_index) const; base::Optional<CellRef> GetCell(int cell_index) const;
}; };
class TemplateObjectDescriptionRef : public HeapObjectRef {
public:
DEFINE_REF_CONSTRUCTOR(TemplateObjectDescription, HeapObjectRef)
Handle<TemplateObjectDescription> object() const;
};
class CellRef : public HeapObjectRef { class CellRef : public HeapObjectRef {
public: public:
DEFINE_REF_CONSTRUCTOR(Cell, HeapObjectRef) DEFINE_REF_CONSTRUCTOR(Cell, HeapObjectRef)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "src/objects/js-promise.h" #include "src/objects/js-promise.h"
#include "src/objects/js-regexp-inl.h" #include "src/objects/js-regexp-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/template-objects.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -84,6 +85,8 @@ Reduction JSCreateLowering::Reduce(Node* node) { ...@@ -84,6 +85,8 @@ Reduction JSCreateLowering::Reduce(Node* node) {
return ReduceJSCreateLiteralArrayOrObject(node); return ReduceJSCreateLiteralArrayOrObject(node);
case IrOpcode::kJSCreateLiteralRegExp: case IrOpcode::kJSCreateLiteralRegExp:
return ReduceJSCreateLiteralRegExp(node); return ReduceJSCreateLiteralRegExp(node);
case IrOpcode::kJSGetTemplateObject:
return ReduceJSGetTemplateObject(node);
case IrOpcode::kJSCreateEmptyLiteralArray: case IrOpcode::kJSCreateEmptyLiteralArray:
return ReduceJSCreateEmptyLiteralArray(node); return ReduceJSCreateEmptyLiteralArray(node);
case IrOpcode::kJSCreateEmptyLiteralObject: case IrOpcode::kJSCreateEmptyLiteralObject:
...@@ -1073,15 +1076,10 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) { ...@@ -1073,15 +1076,10 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
ProcessedFeedback const& feedback =
FeedbackVectorRef feedback_vector(broker(), p.feedback().vector); broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback());
ObjectRef feedback = feedback_vector.get(p.feedback().slot); if (!feedback.IsInsufficient()) {
// TODO(turbofan): we should consider creating a ProcessedFeedback for AllocationSiteRef site = feedback.AsLiteral().value();
// allocation sites/boiler plates so that we use GetFeedback here. Then
// we can eventually get rid of the additional copy of feedback slots that
// we currently have in FeedbackVectorData.
if (feedback.IsAllocationSite()) {
AllocationSiteRef site = feedback.AsAllocationSite();
if (site.IsFastLiteral()) { if (site.IsFastLiteral()) {
AllocationType allocation = AllocationType::kYoung; AllocationType allocation = AllocationType::kYoung;
if (FLAG_allocation_site_pretenuring) { if (FLAG_allocation_site_pretenuring) {
...@@ -1095,20 +1093,17 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) { ...@@ -1095,20 +1093,17 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
return Replace(value); return Replace(value);
} }
} }
return NoChange(); return NoChange();
} }
Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) { Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode()); DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
FeedbackParameter const& p = FeedbackParameterOf(node->op()); FeedbackParameter const& p = FeedbackParameterOf(node->op());
FeedbackVectorRef fv(broker(), p.feedback().vector); ProcessedFeedback const& feedback =
ObjectRef feedback = fv.get(p.feedback().slot); broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback());
// TODO(turbofan): we should consider creating a ProcessedFeedback for if (!feedback.IsInsufficient()) {
// allocation sites/boiler plates so that we use GetFeedback here. Then AllocationSiteRef site = feedback.AsLiteral().value();
// we can eventually get rid of the additional copy of feedback slots that
// we currently have in FeedbackVectorData.
if (feedback.IsAllocationSite()) {
AllocationSiteRef site = feedback.AsAllocationSite();
DCHECK(!site.PointsToLiteral()); DCHECK(!site.PointsToLiteral());
MapRef initial_map = MapRef initial_map =
native_context().GetInitialJSArrayMap(site.GetElementsKind()); native_context().GetInitialJSArrayMap(site.GetElementsKind());
...@@ -1162,22 +1157,30 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) { ...@@ -1162,22 +1157,30 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
ProcessedFeedback const& feedback =
FeedbackVectorRef feedback_vector(broker(), p.feedback().vector); broker()->GetFeedbackForRegExpLiteral(p.feedback());
ObjectRef feedback = feedback_vector.get(p.feedback().slot); if (!feedback.IsInsufficient()) {
// TODO(turbofan): we should consider creating a ProcessedFeedback for JSRegExpRef literal = feedback.AsRegExpLiteral().value();
// allocation sites/boiler plates so that we use GetFeedback here. Then Node* value = effect = AllocateLiteralRegExp(effect, control, literal);
// we can eventually get rid of the additional copy of feedback slots that
// we currently have in FeedbackVectorData.
if (feedback.IsJSRegExp()) {
JSRegExpRef boilerplate = feedback.AsJSRegExp();
Node* value = effect = AllocateLiteralRegExp(effect, control, boilerplate);
ReplaceWithValue(node, value, effect, control); ReplaceWithValue(node, value, effect, control);
return Replace(value); return Replace(value);
} }
return NoChange(); return NoChange();
} }
Reduction JSCreateLowering::ReduceJSGetTemplateObject(Node* node) {
DCHECK_EQ(IrOpcode::kJSGetTemplateObject, node->opcode());
GetTemplateObjectParameters const& parameters =
GetTemplateObjectParametersOf(node->op());
SharedFunctionInfoRef shared(broker(), parameters.shared());
JSArrayRef template_object = shared.GetTemplateObject(
TemplateObjectDescriptionRef(broker(), parameters.description()),
parameters.feedback());
Node* value = jsgraph()->Constant(template_object);
ReplaceWithValue(node, value);
return Replace(value);
}
Reduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) { Reduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode()); DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
const CreateFunctionContextParameters& parameters = const CreateFunctionContextParameters& parameters =
......
...@@ -67,6 +67,7 @@ class V8_EXPORT_PRIVATE JSCreateLowering final ...@@ -67,6 +67,7 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
Reduction ReduceJSCreateCatchContext(Node* node); Reduction ReduceJSCreateCatchContext(Node* node);
Reduction ReduceJSCreateBlockContext(Node* node); Reduction ReduceJSCreateBlockContext(Node* node);
Reduction ReduceJSCreateGeneratorObject(Node* node); Reduction ReduceJSCreateGeneratorObject(Node* node);
Reduction ReduceJSGetTemplateObject(Node* node);
Reduction ReduceNewArray( Reduction ReduceNewArray(
Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind, Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind,
AllocationType allocation, AllocationType allocation,
......
...@@ -562,6 +562,10 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) { ...@@ -562,6 +562,10 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
} }
} }
void JSGenericLowering::LowerJSGetTemplateObject(Node* node) {
UNREACHABLE(); // Eliminated in native context specialization.
}
void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) { void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
FeedbackParameter const& p = FeedbackParameterOf(node->op()); FeedbackParameter const& p = FeedbackParameterOf(node->op());
......
This diff is collapsed.
...@@ -125,6 +125,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -125,6 +125,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
FeedbackSource const& source); FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForInstanceOf( ProcessedFeedback const& GetFeedbackForInstanceOf(
FeedbackSource const& source); FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForArrayOrObjectLiteral(
FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForRegExpLiteral(
FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForTemplateObject(
FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForPropertyAccess( ProcessedFeedback const& GetFeedbackForPropertyAccess(
FeedbackSource const& source, AccessMode mode, FeedbackSource const& source, AccessMode mode,
base::Optional<NameRef> static_name); base::Optional<NameRef> static_name);
...@@ -143,6 +149,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -143,6 +149,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
ProcessedFeedback const& ProcessFeedbackForPropertyAccess( ProcessedFeedback const& ProcessFeedbackForPropertyAccess(
FeedbackSource const& source, AccessMode mode, FeedbackSource const& source, AccessMode mode,
base::Optional<NameRef> static_name); base::Optional<NameRef> static_name);
ProcessedFeedback const& ProcessFeedbackForArrayOrObjectLiteral(
FeedbackSource const& source);
ProcessedFeedback const& ProcessFeedbackForRegExpLiteral(
FeedbackSource const& source);
ProcessedFeedback const& ProcessFeedbackForTemplateObject(
FeedbackSource const& source);
bool FeedbackIsInsufficient(FeedbackSource const& source) const; bool FeedbackIsInsufficient(FeedbackSource const& source) const;
...@@ -182,6 +194,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -182,6 +194,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
ProcessedFeedback const& ReadFeedbackForPropertyAccess( ProcessedFeedback const& ReadFeedbackForPropertyAccess(
FeedbackSource const& source, AccessMode mode, FeedbackSource const& source, AccessMode mode,
base::Optional<NameRef> static_name); base::Optional<NameRef> static_name);
ProcessedFeedback const& ReadFeedbackForArrayOrObjectLiteral(
FeedbackSource const& source);
ProcessedFeedback const& ReadFeedbackForRegExpLiteral(
FeedbackSource const& source);
ProcessedFeedback const& ReadFeedbackForTemplateObject(
FeedbackSource const& source);
void InitializeRefsMap(); void InitializeRefsMap();
void CollectArrayAndObjectPrototypes(); void CollectArrayAndObjectPrototypes();
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "src/heap/factory-inl.h" #include "src/heap/factory-inl.h"
#include "src/objects/map.h" #include "src/objects/map.h"
#include "src/objects/scope-info.h" #include "src/objects/scope-info.h"
#include "src/objects/template-objects.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -73,7 +74,9 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) { ...@@ -73,7 +74,9 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) {
} }
case IrOpcode::kJSCreateEmptyLiteralArray: { case IrOpcode::kJSCreateEmptyLiteralArray: {
FeedbackParameter const& p = FeedbackParameterOf(node->op()); FeedbackParameter const& p = FeedbackParameterOf(node->op());
FeedbackVectorRef(broker(), p.feedback().vector).Serialize(); if (p.feedback().IsValid()) {
broker()->ProcessFeedbackForArrayOrObjectLiteral(p.feedback());
}
break; break;
} }
case IrOpcode::kJSCreateFunctionContext: { case IrOpcode::kJSCreateFunctionContext: {
...@@ -85,12 +88,25 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) { ...@@ -85,12 +88,25 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) {
case IrOpcode::kJSCreateLiteralArray: case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateLiteralObject: { case IrOpcode::kJSCreateLiteralObject: {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
FeedbackVectorRef(broker(), p.feedback().vector).Serialize(); if (p.feedback().IsValid()) {
broker()->ProcessFeedbackForArrayOrObjectLiteral(p.feedback());
}
break; break;
} }
case IrOpcode::kJSCreateLiteralRegExp: { case IrOpcode::kJSCreateLiteralRegExp: {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
FeedbackVectorRef(broker(), p.feedback().vector).Serialize(); if (p.feedback().IsValid()) {
broker()->ProcessFeedbackForRegExpLiteral(p.feedback());
}
break;
}
case IrOpcode::kJSGetTemplateObject: {
GetTemplateObjectParameters const& p =
GetTemplateObjectParametersOf(node->op());
SharedFunctionInfoRef shared(broker(), p.shared());
TemplateObjectDescriptionRef description(broker(), p.description());
shared.GetTemplateObject(description, p.feedback(),
SerializationPolicy::kSerializeIfNeeded);
break; break;
} }
case IrOpcode::kJSCreateWithContext: { case IrOpcode::kJSCreateWithContext: {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "src/compiler/operator.h" #include "src/compiler/operator.h"
#include "src/handles/handles-inl.h" #include "src/handles/handles-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/template-objects.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -472,6 +473,34 @@ const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf( ...@@ -472,6 +473,34 @@ const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf(
return OpParameter<CreateBoundFunctionParameters>(op); return OpParameter<CreateBoundFunctionParameters>(op);
} }
bool operator==(GetTemplateObjectParameters const& lhs,
GetTemplateObjectParameters const& rhs) {
return lhs.description().location() == rhs.description().location() &&
lhs.shared().location() == rhs.shared().location() &&
lhs.feedback() == rhs.feedback();
}
bool operator!=(GetTemplateObjectParameters const& lhs,
GetTemplateObjectParameters const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(GetTemplateObjectParameters const& p) {
return base::hash_combine(p.description().location(), p.shared().location(),
FeedbackSource::Hash()(p.feedback()));
}
std::ostream& operator<<(std::ostream& os,
GetTemplateObjectParameters const& p) {
return os << Brief(*p.description()) << ", " << Brief(*p.shared());
}
const GetTemplateObjectParameters& GetTemplateObjectParametersOf(
const Operator* op) {
DCHECK(op->opcode() == IrOpcode::kJSGetTemplateObject);
return OpParameter<GetTemplateObjectParameters>(op);
}
bool operator==(CreateClosureParameters const& lhs, bool operator==(CreateClosureParameters const& lhs,
CreateClosureParameters const& rhs) { CreateClosureParameters const& rhs) {
return lhs.allocation() == rhs.allocation() && return lhs.allocation() == rhs.allocation() &&
...@@ -1282,6 +1311,18 @@ const Operator* JSOperatorBuilder::CreateLiteralObject( ...@@ -1282,6 +1311,18 @@ const Operator* JSOperatorBuilder::CreateLiteralObject(
parameters); // parameter parameters); // parameter
} }
const Operator* JSOperatorBuilder::GetTemplateObject(
Handle<TemplateObjectDescription> description,
Handle<SharedFunctionInfo> shared, FeedbackSource const& feedback) {
GetTemplateObjectParameters parameters(description, shared, feedback);
return new (zone()) Operator1<GetTemplateObjectParameters>( // --
IrOpcode::kJSGetTemplateObject, // opcode
Operator::kEliminatable, // properties
"JSGetTemplateObject", // name
0, 1, 1, 1, 1, 0, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::CloneObject(FeedbackSource const& feedback, const Operator* JSOperatorBuilder::CloneObject(FeedbackSource const& feedback,
int literal_flags) { int literal_flags) {
CloneObjectParameters parameters(feedback, literal_flags); CloneObjectParameters parameters(feedback, literal_flags);
......
...@@ -598,6 +598,35 @@ std::ostream& operator<<(std::ostream&, CreateClosureParameters const&); ...@@ -598,6 +598,35 @@ std::ostream& operator<<(std::ostream&, CreateClosureParameters const&);
const CreateClosureParameters& CreateClosureParametersOf(const Operator* op); const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
class GetTemplateObjectParameters final {
public:
GetTemplateObjectParameters(Handle<TemplateObjectDescription> description,
Handle<SharedFunctionInfo> shared,
FeedbackSource const& feedback)
: description_(description), shared_(shared), feedback_(feedback) {}
Handle<TemplateObjectDescription> description() const { return description_; }
Handle<SharedFunctionInfo> shared() const { return shared_; }
FeedbackSource const& feedback() const { return feedback_; }
private:
Handle<TemplateObjectDescription> const description_;
Handle<SharedFunctionInfo> const shared_;
FeedbackSource const feedback_;
};
bool operator==(GetTemplateObjectParameters const&,
GetTemplateObjectParameters const&);
bool operator!=(GetTemplateObjectParameters const&,
GetTemplateObjectParameters const&);
size_t hash_value(GetTemplateObjectParameters const&);
std::ostream& operator<<(std::ostream&, GetTemplateObjectParameters const&);
const GetTemplateObjectParameters& GetTemplateObjectParametersOf(
const Operator* op);
// Defines shared information for the literal that should be created. This is // Defines shared information for the literal that should be created. This is
// used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and // used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and
// JSCreateLiteralRegExp operators. // JSCreateLiteralRegExp operators.
...@@ -767,7 +796,6 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final ...@@ -767,7 +796,6 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* CreateEmptyLiteralArray(FeedbackSource const& feedback); const Operator* CreateEmptyLiteralArray(FeedbackSource const& feedback);
const Operator* CreateArrayFromIterable(); const Operator* CreateArrayFromIterable();
const Operator* CreateEmptyLiteralObject(); const Operator* CreateEmptyLiteralObject();
const Operator* CreateLiteralObject( const Operator* CreateLiteralObject(
Handle<ObjectBoilerplateDescription> constant, Handle<ObjectBoilerplateDescription> constant,
FeedbackSource const& feedback, int literal_flags, FeedbackSource const& feedback, int literal_flags,
...@@ -778,6 +806,10 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final ...@@ -778,6 +806,10 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
FeedbackSource const& feedback, FeedbackSource const& feedback,
int literal_flags); int literal_flags);
const Operator* GetTemplateObject(
Handle<TemplateObjectDescription> description,
Handle<SharedFunctionInfo> shared, FeedbackSource const& feedback);
const Operator* CallForwardVarargs(size_t arity, uint32_t start_index); const Operator* CallForwardVarargs(size_t arity, uint32_t start_index);
const Operator* Call( const Operator* Call(
size_t arity, CallFrequency const& frequency = CallFrequency(), size_t arity, CallFrequency const& frequency = CallFrequency(),
......
...@@ -156,7 +156,8 @@ ...@@ -156,7 +156,8 @@
V(JSCreateObject) \ V(JSCreateObject) \
V(JSCreatePromise) \ V(JSCreatePromise) \
V(JSCreateStringIterator) \ V(JSCreateStringIterator) \
V(JSCreateTypedArray) V(JSCreateTypedArray) \
V(JSGetTemplateObject)
#define JS_OBJECT_OP_LIST(V) \ #define JS_OBJECT_OP_LIST(V) \
JS_CREATE_OP_LIST(V) \ JS_CREATE_OP_LIST(V) \
......
...@@ -41,6 +41,7 @@ bool OperatorProperties::NeedsExactContext(const Operator* op) { ...@@ -41,6 +41,7 @@ bool OperatorProperties::NeedsExactContext(const Operator* op) {
case IrOpcode::kJSCreateEmptyLiteralObject: case IrOpcode::kJSCreateEmptyLiteralObject:
case IrOpcode::kJSCreateArrayFromIterable: case IrOpcode::kJSCreateArrayFromIterable:
case IrOpcode::kJSCreateLiteralRegExp: case IrOpcode::kJSCreateLiteralRegExp:
case IrOpcode::kJSGetTemplateObject:
case IrOpcode::kJSForInEnumerate: case IrOpcode::kJSForInEnumerate:
case IrOpcode::kJSForInNext: case IrOpcode::kJSForInNext:
case IrOpcode::kJSForInPrepare: case IrOpcode::kJSForInPrepare:
......
...@@ -18,7 +18,10 @@ class ElementAccessFeedback; ...@@ -18,7 +18,10 @@ class ElementAccessFeedback;
class ForInFeedback; class ForInFeedback;
class GlobalAccessFeedback; class GlobalAccessFeedback;
class InstanceOfFeedback; class InstanceOfFeedback;
class LiteralFeedback;
class NamedAccessFeedback; class NamedAccessFeedback;
class RegExpLiteralFeedback;
class TemplateObjectFeedback;
class ProcessedFeedback : public ZoneObject { class ProcessedFeedback : public ZoneObject {
public: public:
...@@ -31,7 +34,10 @@ class ProcessedFeedback : public ZoneObject { ...@@ -31,7 +34,10 @@ class ProcessedFeedback : public ZoneObject {
kForIn, kForIn,
kGlobalAccess, kGlobalAccess,
kInstanceOf, kInstanceOf,
kLiteral,
kNamedAccess, kNamedAccess,
kRegExpLiteral,
kTemplateObject,
}; };
Kind kind() const { return kind_; } Kind kind() const { return kind_; }
...@@ -46,6 +52,9 @@ class ProcessedFeedback : public ZoneObject { ...@@ -46,6 +52,9 @@ class ProcessedFeedback : public ZoneObject {
GlobalAccessFeedback const& AsGlobalAccess() const; GlobalAccessFeedback const& AsGlobalAccess() const;
InstanceOfFeedback const& AsInstanceOf() const; InstanceOfFeedback const& AsInstanceOf() const;
NamedAccessFeedback const& AsNamedAccess() const; NamedAccessFeedback const& AsNamedAccess() const;
LiteralFeedback const& AsLiteral() const;
RegExpLiteralFeedback const& AsRegExpLiteral() const;
TemplateObjectFeedback const& AsTemplateObject() const;
protected: protected:
ProcessedFeedback(Kind kind, FeedbackSlotKind slot_kind); ProcessedFeedback(Kind kind, FeedbackSlotKind slot_kind);
...@@ -187,7 +196,9 @@ class SingleValueFeedback : public ProcessedFeedback { ...@@ -187,7 +196,9 @@ class SingleValueFeedback : public ProcessedFeedback {
(K == kBinaryOperation && slot_kind == FeedbackSlotKind::kBinaryOp) || (K == kBinaryOperation && slot_kind == FeedbackSlotKind::kBinaryOp) ||
(K == kCompareOperation && slot_kind == FeedbackSlotKind::kCompareOp) || (K == kCompareOperation && slot_kind == FeedbackSlotKind::kCompareOp) ||
(K == kForIn && slot_kind == FeedbackSlotKind::kForIn) || (K == kForIn && slot_kind == FeedbackSlotKind::kForIn) ||
(K == kInstanceOf && slot_kind == FeedbackSlotKind::kInstanceOf)); (K == kInstanceOf && slot_kind == FeedbackSlotKind::kInstanceOf) ||
((K == kLiteral || K == kRegExpLiteral || K == kTemplateObject) &&
slot_kind == FeedbackSlotKind::kLiteral));
} }
T value() const { return value_; } T value() const { return value_; }
...@@ -202,6 +213,24 @@ class InstanceOfFeedback ...@@ -202,6 +213,24 @@ class InstanceOfFeedback
using SingleValueFeedback::SingleValueFeedback; using SingleValueFeedback::SingleValueFeedback;
}; };
class LiteralFeedback
: public SingleValueFeedback<AllocationSiteRef,
ProcessedFeedback::kLiteral> {
using SingleValueFeedback::SingleValueFeedback;
};
class RegExpLiteralFeedback
: public SingleValueFeedback<JSRegExpRef,
ProcessedFeedback::kRegExpLiteral> {
using SingleValueFeedback::SingleValueFeedback;
};
class TemplateObjectFeedback
: public SingleValueFeedback<JSArrayRef,
ProcessedFeedback::kTemplateObject> {
using SingleValueFeedback::SingleValueFeedback;
};
class BinaryOperationFeedback class BinaryOperationFeedback
: public SingleValueFeedback<BinaryOperationHint, : public SingleValueFeedback<BinaryOperationHint,
ProcessedFeedback::kBinaryOperation> { ProcessedFeedback::kBinaryOperation> {
......
...@@ -43,7 +43,6 @@ namespace compiler { ...@@ -43,7 +43,6 @@ namespace compiler {
V(CallRuntime) \ V(CallRuntime) \
V(CloneObject) \ V(CloneObject) \
V(CreateArrayFromIterable) \ V(CreateArrayFromIterable) \
V(CreateEmptyArrayLiteral) \
V(CreateEmptyObjectLiteral) \ V(CreateEmptyObjectLiteral) \
V(CreateMappedArguments) \ V(CreateMappedArguments) \
V(CreateRestParameter) \ V(CreateRestParameter) \
...@@ -162,6 +161,7 @@ namespace compiler { ...@@ -162,6 +161,7 @@ namespace compiler {
V(CreateBlockContext) \ V(CreateBlockContext) \
V(CreateCatchContext) \ V(CreateCatchContext) \
V(CreateClosure) \ V(CreateClosure) \
V(CreateEmptyArrayLiteral) \
V(CreateEvalContext) \ V(CreateEvalContext) \
V(CreateFunctionContext) \ V(CreateFunctionContext) \
V(CreateObjectLiteral) \ V(CreateObjectLiteral) \
...@@ -1111,14 +1111,13 @@ void SerializerForBackgroundCompilation::VisitGetSuperConstructor( ...@@ -1111,14 +1111,13 @@ void SerializerForBackgroundCompilation::VisitGetSuperConstructor(
void SerializerForBackgroundCompilation::VisitGetTemplateObject( void SerializerForBackgroundCompilation::VisitGetTemplateObject(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
ObjectRef description( TemplateObjectDescriptionRef description(
broker(), iterator->GetConstantForIndexOperand(0, broker()->isolate())); broker(), iterator->GetConstantForIndexOperand(0, broker()->isolate()));
FeedbackSlot slot = iterator->GetSlotOperand(1); FeedbackSlot slot = iterator->GetSlotOperand(1);
FeedbackVectorRef feedback_vector_ref(broker(), feedback_vector()); FeedbackSource source(feedback_vector(), slot);
SharedFunctionInfoRef shared(broker(), environment()->function().shared()); SharedFunctionInfoRef shared(broker(), environment()->function().shared());
JSArrayRef template_object = JSArrayRef template_object = shared.GetTemplateObject(
shared.GetTemplateObject(description, feedback_vector_ref, slot, description, source, SerializationPolicy::kSerializeIfNeeded);
SerializationPolicy::kSerializeIfNeeded);
environment()->accumulator_hints().Clear(); environment()->accumulator_hints().Clear();
environment()->accumulator_hints().AddConstant(template_object.object(), environment()->accumulator_hints().AddConstant(template_object.object(),
zone()); zone());
...@@ -1467,6 +1466,9 @@ void SerializerForBackgroundCompilation::VisitCreateRegExpLiteral( ...@@ -1467,6 +1466,9 @@ void SerializerForBackgroundCompilation::VisitCreateRegExpLiteral(
Handle<String> constant_pattern = Handle<String>::cast( Handle<String> constant_pattern = Handle<String>::cast(
iterator->GetConstantForIndexOperand(0, broker()->isolate())); iterator->GetConstantForIndexOperand(0, broker()->isolate()));
StringRef description(broker(), constant_pattern); StringRef description(broker(), constant_pattern);
FeedbackSlot slot = iterator->GetSlotOperand(1);
FeedbackSource source(feedback_vector(), slot);
broker()->ProcessFeedbackForRegExpLiteral(source);
environment()->accumulator_hints().Clear(); environment()->accumulator_hints().Clear();
} }
...@@ -1477,6 +1479,17 @@ void SerializerForBackgroundCompilation::VisitCreateArrayLiteral( ...@@ -1477,6 +1479,17 @@ void SerializerForBackgroundCompilation::VisitCreateArrayLiteral(
iterator->GetConstantForIndexOperand(0, broker()->isolate())); iterator->GetConstantForIndexOperand(0, broker()->isolate()));
ArrayBoilerplateDescriptionRef description(broker(), ArrayBoilerplateDescriptionRef description(broker(),
array_boilerplate_description); array_boilerplate_description);
FeedbackSlot slot = iterator->GetSlotOperand(1);
FeedbackSource source(feedback_vector(), slot);
broker()->ProcessFeedbackForArrayOrObjectLiteral(source);
environment()->accumulator_hints().Clear();
}
void SerializerForBackgroundCompilation::VisitCreateEmptyArrayLiteral(
BytecodeArrayIterator* iterator) {
FeedbackSlot slot = iterator->GetSlotOperand(0);
FeedbackSource source(feedback_vector(), slot);
broker()->ProcessFeedbackForArrayOrObjectLiteral(source);
environment()->accumulator_hints().Clear(); environment()->accumulator_hints().Clear();
} }
...@@ -1486,6 +1499,9 @@ void SerializerForBackgroundCompilation::VisitCreateObjectLiteral( ...@@ -1486,6 +1499,9 @@ void SerializerForBackgroundCompilation::VisitCreateObjectLiteral(
Handle<ObjectBoilerplateDescription>::cast( Handle<ObjectBoilerplateDescription>::cast(
iterator->GetConstantForIndexOperand(0, broker()->isolate())); iterator->GetConstantForIndexOperand(0, broker()->isolate()));
ObjectBoilerplateDescriptionRef description(broker(), constant_properties); ObjectBoilerplateDescriptionRef description(broker(), constant_properties);
FeedbackSlot slot = iterator->GetSlotOperand(1);
FeedbackSource source(feedback_vector(), slot);
broker()->ProcessFeedbackForArrayOrObjectLiteral(source);
environment()->accumulator_hints().Clear(); environment()->accumulator_hints().Clear();
} }
......
...@@ -1339,6 +1339,10 @@ Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) { ...@@ -1339,6 +1339,10 @@ Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
return Type::OtherObject(); return Type::OtherObject();
} }
Type Typer::Visitor::TypeJSGetTemplateObject(Node* node) {
return Type::Array();
}
Type Typer::Visitor::TypeJSLoadProperty(Node* node) { Type Typer::Visitor::TypeJSLoadProperty(Node* node) {
return Type::NonInternal(); return Type::NonInternal();
} }
......
...@@ -732,6 +732,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { ...@@ -732,6 +732,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
// Type is OtherObject. // Type is OtherObject.
CheckTypeIs(node, Type::OtherObject()); CheckTypeIs(node, Type::OtherObject());
break; break;
case IrOpcode::kJSGetTemplateObject:
// Type is Array
CheckTypeIs(node, Type::Array());
break;
case IrOpcode::kJSLoadProperty: case IrOpcode::kJSLoadProperty:
// Type can be anything. // Type can be anything.
CheckTypeIs(node, Type::Any()); CheckTypeIs(node, Type::Any());
......
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