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 @@
#include "src/objects/literal-objects-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
#include "src/objects/template-objects-inl.h"
#include "src/objects/template-objects.h"
namespace v8 {
namespace internal {
......@@ -2090,12 +2090,13 @@ void BytecodeGraphBuilder::VisitCloneObject() {
void BytecodeGraphBuilder::VisitGetTemplateObject() {
DisallowHeapAccessIf no_heap_access(FLAG_concurrent_inlining);
FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
ObjectRef description(
FeedbackSource source =
CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
TemplateObjectDescriptionRef description(
broker(), bytecode_iterator().GetConstantForIndexOperand(0, isolate()));
JSArrayRef template_object =
shared_info().GetTemplateObject(description, feedback_vector(), slot);
environment()->BindAccumulator(jsgraph()->Constant(template_object));
Node* template_object = NewNode(javascript()->GetTemplateObject(
description.object(), shared_info().object(), source));
environment()->BindAccumulator(template_object);
}
Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
......
......@@ -29,7 +29,6 @@ class NativeContext;
class ScriptContextTable;
namespace compiler {
// Whether we are loading a property or storing to a property.
// For a store during literal creation, do not walk up the prototype chain.
enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas };
......@@ -95,10 +94,12 @@ enum class OddballType : uint8_t {
V(PropertyCell) \
V(SharedFunctionInfo) \
V(SourceTextModule) \
V(TemplateObjectDescription) \
/* Subtypes of Object */ \
V(HeapObject)
class CompilationDependencies;
struct FeedbackSource;
class JSHeapBroker;
class ObjectData;
class PerIsolateCompilerCache;
......@@ -342,6 +343,8 @@ class JSRegExpRef : public JSObjectRef {
ObjectRef source() const;
ObjectRef flags() const;
ObjectRef last_index() const;
void SerializeAsRegExpBoilerplate();
};
class HeapNumberRef : public HeapObjectRef {
......@@ -494,7 +497,6 @@ class FeedbackVectorRef : public HeapObjectRef {
double invocation_count() const;
void Serialize();
ObjectRef get(FeedbackSlot slot) const;
FeedbackCellRef GetClosureFeedbackCell(int index) const;
};
......@@ -533,6 +535,9 @@ class AllocationSiteRef : public HeapObjectRef {
//
// If PointsToLiteral() is false, then IsFastLiteral() is also false.
bool IsFastLiteral() const;
void SerializeBoilerplate();
// We only serialize boilerplate if IsFastLiteral is true.
base::Optional<JSObjectRef> boilerplate() const;
......@@ -789,7 +794,7 @@ class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef {
// wraps the retrieval of the template object and creates it if
// necessary.
JSArrayRef GetTemplateObject(
ObjectRef description, FeedbackVectorRef vector, FeedbackSlot slot,
TemplateObjectDescriptionRef description, FeedbackSource const& source,
SerializationPolicy policy = SerializationPolicy::kAssumeSerialized);
void SerializeFunctionTemplateInfo();
......@@ -843,6 +848,13 @@ class SourceTextModuleRef : public HeapObjectRef {
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 {
public:
DEFINE_REF_CONSTRUCTOR(Cell, HeapObjectRef)
......
......@@ -26,6 +26,7 @@
#include "src/objects/js-promise.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/template-objects.h"
namespace v8 {
namespace internal {
......@@ -84,6 +85,8 @@ Reduction JSCreateLowering::Reduce(Node* node) {
return ReduceJSCreateLiteralArrayOrObject(node);
case IrOpcode::kJSCreateLiteralRegExp:
return ReduceJSCreateLiteralRegExp(node);
case IrOpcode::kJSGetTemplateObject:
return ReduceJSGetTemplateObject(node);
case IrOpcode::kJSCreateEmptyLiteralArray:
return ReduceJSCreateEmptyLiteralArray(node);
case IrOpcode::kJSCreateEmptyLiteralObject:
......@@ -1073,15 +1076,10 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
FeedbackVectorRef feedback_vector(broker(), p.feedback().vector);
ObjectRef feedback = feedback_vector.get(p.feedback().slot);
// TODO(turbofan): we should consider creating a ProcessedFeedback for
// 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();
ProcessedFeedback const& feedback =
broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback());
if (!feedback.IsInsufficient()) {
AllocationSiteRef site = feedback.AsLiteral().value();
if (site.IsFastLiteral()) {
AllocationType allocation = AllocationType::kYoung;
if (FLAG_allocation_site_pretenuring) {
......@@ -1095,20 +1093,17 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
return Replace(value);
}
}
return NoChange();
}
Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
FeedbackParameter const& p = FeedbackParameterOf(node->op());
FeedbackVectorRef fv(broker(), p.feedback().vector);
ObjectRef feedback = fv.get(p.feedback().slot);
// TODO(turbofan): we should consider creating a ProcessedFeedback for
// 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();
ProcessedFeedback const& feedback =
broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback());
if (!feedback.IsInsufficient()) {
AllocationSiteRef site = feedback.AsLiteral().value();
DCHECK(!site.PointsToLiteral());
MapRef initial_map =
native_context().GetInitialJSArrayMap(site.GetElementsKind());
......@@ -1162,22 +1157,30 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
FeedbackVectorRef feedback_vector(broker(), p.feedback().vector);
ObjectRef feedback = feedback_vector.get(p.feedback().slot);
// TODO(turbofan): we should consider creating a ProcessedFeedback for
// 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.IsJSRegExp()) {
JSRegExpRef boilerplate = feedback.AsJSRegExp();
Node* value = effect = AllocateLiteralRegExp(effect, control, boilerplate);
ProcessedFeedback const& feedback =
broker()->GetFeedbackForRegExpLiteral(p.feedback());
if (!feedback.IsInsufficient()) {
JSRegExpRef literal = feedback.AsRegExpLiteral().value();
Node* value = effect = AllocateLiteralRegExp(effect, control, literal);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
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) {
DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
const CreateFunctionContextParameters& parameters =
......
......@@ -67,6 +67,7 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
Reduction ReduceJSCreateCatchContext(Node* node);
Reduction ReduceJSCreateBlockContext(Node* node);
Reduction ReduceJSCreateGeneratorObject(Node* node);
Reduction ReduceJSGetTemplateObject(Node* node);
Reduction ReduceNewArray(
Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind,
AllocationType allocation,
......
......@@ -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) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
FeedbackParameter const& p = FeedbackParameterOf(node->op());
......
This diff is collapsed.
......@@ -125,6 +125,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForInstanceOf(
FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForArrayOrObjectLiteral(
FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForRegExpLiteral(
FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForTemplateObject(
FeedbackSource const& source);
ProcessedFeedback const& GetFeedbackForPropertyAccess(
FeedbackSource const& source, AccessMode mode,
base::Optional<NameRef> static_name);
......@@ -143,6 +149,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
ProcessedFeedback const& ProcessFeedbackForPropertyAccess(
FeedbackSource const& source, AccessMode mode,
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;
......@@ -182,6 +194,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
ProcessedFeedback const& ReadFeedbackForPropertyAccess(
FeedbackSource const& source, AccessMode mode,
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 CollectArrayAndObjectPrototypes();
......
......@@ -12,6 +12,7 @@
#include "src/heap/factory-inl.h"
#include "src/objects/map.h"
#include "src/objects/scope-info.h"
#include "src/objects/template-objects.h"
namespace v8 {
namespace internal {
......@@ -73,7 +74,9 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) {
}
case IrOpcode::kJSCreateEmptyLiteralArray: {
FeedbackParameter const& p = FeedbackParameterOf(node->op());
FeedbackVectorRef(broker(), p.feedback().vector).Serialize();
if (p.feedback().IsValid()) {
broker()->ProcessFeedbackForArrayOrObjectLiteral(p.feedback());
}
break;
}
case IrOpcode::kJSCreateFunctionContext: {
......@@ -85,12 +88,25 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) {
case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateLiteralObject: {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
FeedbackVectorRef(broker(), p.feedback().vector).Serialize();
if (p.feedback().IsValid()) {
broker()->ProcessFeedbackForArrayOrObjectLiteral(p.feedback());
}
break;
}
case IrOpcode::kJSCreateLiteralRegExp: {
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;
}
case IrOpcode::kJSCreateWithContext: {
......
......@@ -11,6 +11,7 @@
#include "src/compiler/operator.h"
#include "src/handles/handles-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/template-objects.h"
namespace v8 {
namespace internal {
......@@ -472,6 +473,34 @@ const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf(
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,
CreateClosureParameters const& rhs) {
return lhs.allocation() == rhs.allocation() &&
......@@ -1282,6 +1311,18 @@ const Operator* JSOperatorBuilder::CreateLiteralObject(
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,
int literal_flags) {
CloneObjectParameters parameters(feedback, literal_flags);
......
......@@ -598,6 +598,35 @@ std::ostream& operator<<(std::ostream&, CreateClosureParameters const&);
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
// used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and
// JSCreateLiteralRegExp operators.
......@@ -767,7 +796,6 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* CreateEmptyLiteralArray(FeedbackSource const& feedback);
const Operator* CreateArrayFromIterable();
const Operator* CreateEmptyLiteralObject();
const Operator* CreateLiteralObject(
Handle<ObjectBoilerplateDescription> constant,
FeedbackSource const& feedback, int literal_flags,
......@@ -778,6 +806,10 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
FeedbackSource const& feedback,
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* Call(
size_t arity, CallFrequency const& frequency = CallFrequency(),
......
......@@ -156,7 +156,8 @@
V(JSCreateObject) \
V(JSCreatePromise) \
V(JSCreateStringIterator) \
V(JSCreateTypedArray)
V(JSCreateTypedArray) \
V(JSGetTemplateObject)
#define JS_OBJECT_OP_LIST(V) \
JS_CREATE_OP_LIST(V) \
......
......@@ -41,6 +41,7 @@ bool OperatorProperties::NeedsExactContext(const Operator* op) {
case IrOpcode::kJSCreateEmptyLiteralObject:
case IrOpcode::kJSCreateArrayFromIterable:
case IrOpcode::kJSCreateLiteralRegExp:
case IrOpcode::kJSGetTemplateObject:
case IrOpcode::kJSForInEnumerate:
case IrOpcode::kJSForInNext:
case IrOpcode::kJSForInPrepare:
......
......@@ -18,7 +18,10 @@ class ElementAccessFeedback;
class ForInFeedback;
class GlobalAccessFeedback;
class InstanceOfFeedback;
class LiteralFeedback;
class NamedAccessFeedback;
class RegExpLiteralFeedback;
class TemplateObjectFeedback;
class ProcessedFeedback : public ZoneObject {
public:
......@@ -31,7 +34,10 @@ class ProcessedFeedback : public ZoneObject {
kForIn,
kGlobalAccess,
kInstanceOf,
kLiteral,
kNamedAccess,
kRegExpLiteral,
kTemplateObject,
};
Kind kind() const { return kind_; }
......@@ -46,6 +52,9 @@ class ProcessedFeedback : public ZoneObject {
GlobalAccessFeedback const& AsGlobalAccess() const;
InstanceOfFeedback const& AsInstanceOf() const;
NamedAccessFeedback const& AsNamedAccess() const;
LiteralFeedback const& AsLiteral() const;
RegExpLiteralFeedback const& AsRegExpLiteral() const;
TemplateObjectFeedback const& AsTemplateObject() const;
protected:
ProcessedFeedback(Kind kind, FeedbackSlotKind slot_kind);
......@@ -187,7 +196,9 @@ class SingleValueFeedback : public ProcessedFeedback {
(K == kBinaryOperation && slot_kind == FeedbackSlotKind::kBinaryOp) ||
(K == kCompareOperation && slot_kind == FeedbackSlotKind::kCompareOp) ||
(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_; }
......@@ -202,6 +213,24 @@ class InstanceOfFeedback
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
: public SingleValueFeedback<BinaryOperationHint,
ProcessedFeedback::kBinaryOperation> {
......
......@@ -43,7 +43,6 @@ namespace compiler {
V(CallRuntime) \
V(CloneObject) \
V(CreateArrayFromIterable) \
V(CreateEmptyArrayLiteral) \
V(CreateEmptyObjectLiteral) \
V(CreateMappedArguments) \
V(CreateRestParameter) \
......@@ -162,6 +161,7 @@ namespace compiler {
V(CreateBlockContext) \
V(CreateCatchContext) \
V(CreateClosure) \
V(CreateEmptyArrayLiteral) \
V(CreateEvalContext) \
V(CreateFunctionContext) \
V(CreateObjectLiteral) \
......@@ -1111,14 +1111,13 @@ void SerializerForBackgroundCompilation::VisitGetSuperConstructor(
void SerializerForBackgroundCompilation::VisitGetTemplateObject(
BytecodeArrayIterator* iterator) {
ObjectRef description(
TemplateObjectDescriptionRef description(
broker(), iterator->GetConstantForIndexOperand(0, broker()->isolate()));
FeedbackSlot slot = iterator->GetSlotOperand(1);
FeedbackVectorRef feedback_vector_ref(broker(), feedback_vector());
FeedbackSource source(feedback_vector(), slot);
SharedFunctionInfoRef shared(broker(), environment()->function().shared());
JSArrayRef template_object =
shared.GetTemplateObject(description, feedback_vector_ref, slot,
SerializationPolicy::kSerializeIfNeeded);
JSArrayRef template_object = shared.GetTemplateObject(
description, source, SerializationPolicy::kSerializeIfNeeded);
environment()->accumulator_hints().Clear();
environment()->accumulator_hints().AddConstant(template_object.object(),
zone());
......@@ -1467,6 +1466,9 @@ void SerializerForBackgroundCompilation::VisitCreateRegExpLiteral(
Handle<String> constant_pattern = Handle<String>::cast(
iterator->GetConstantForIndexOperand(0, broker()->isolate()));
StringRef description(broker(), constant_pattern);
FeedbackSlot slot = iterator->GetSlotOperand(1);
FeedbackSource source(feedback_vector(), slot);
broker()->ProcessFeedbackForRegExpLiteral(source);
environment()->accumulator_hints().Clear();
}
......@@ -1477,6 +1479,17 @@ void SerializerForBackgroundCompilation::VisitCreateArrayLiteral(
iterator->GetConstantForIndexOperand(0, broker()->isolate()));
ArrayBoilerplateDescriptionRef description(broker(),
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();
}
......@@ -1486,6 +1499,9 @@ void SerializerForBackgroundCompilation::VisitCreateObjectLiteral(
Handle<ObjectBoilerplateDescription>::cast(
iterator->GetConstantForIndexOperand(0, broker()->isolate()));
ObjectBoilerplateDescriptionRef description(broker(), constant_properties);
FeedbackSlot slot = iterator->GetSlotOperand(1);
FeedbackSource source(feedback_vector(), slot);
broker()->ProcessFeedbackForArrayOrObjectLiteral(source);
environment()->accumulator_hints().Clear();
}
......
......@@ -1339,6 +1339,10 @@ Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
return Type::OtherObject();
}
Type Typer::Visitor::TypeJSGetTemplateObject(Node* node) {
return Type::Array();
}
Type Typer::Visitor::TypeJSLoadProperty(Node* node) {
return Type::NonInternal();
}
......
......@@ -732,6 +732,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
// Type is OtherObject.
CheckTypeIs(node, Type::OtherObject());
break;
case IrOpcode::kJSGetTemplateObject:
// Type is Array
CheckTypeIs(node, Type::Array());
break;
case IrOpcode::kJSLoadProperty:
// Type can be anything.
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