Commit 855b88ae authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[turbofan] Properly optimize literals in inlined functions.

When inlining based on SharedFunctionInfo rather than based on concrete
JSFunction, we weren't able to properly optimize array, object and
regexp literals inside the inlinee, because we didn't know the concrete
FeedbackVector for the inlinee inside JSCreateLowering. This was because
JSCreateLowering wasn't properly updated after the literals moved to the
FeedbackVector. Now with this CL we also have the VectorSlotPair on the
literal creation operators, just like we do for property accesses and
calls, and are thus able to always access the appropriate FeedbackVector
and optimize the literal creation.

The impact is illustrated by the micro-benchmark on the tracking bug,
which goes from

  createEmptyArrayLiteral: 1846 ms.
  createShallowArrayLiteral: 1868 ms.
  createShallowObjectLiteral: 2246 ms.

to

  createEmptyArrayLiteral: 1175 ms.
  createShallowArrayLiteral: 1187 ms.
  createShallowObjectLiteral: 1195 ms.

with this CL, so up to 2x faster now.

Drive-by-fix: Also remove the unused CreateEmptyObjectLiteral builtin
and cleanup the names of the other builtins to be consistent with the
names of the TurboFan operators and Ignition bytecodes.

Bug: v8:6856
Change-Id: I453828d019b27c9aa1344edac0dd84e91a457097
Reviewed-on: https://chromium-review.googlesource.com/680656
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48140}
parent 63f9ee16
......@@ -90,27 +90,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r3, r2, r1, r0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r3, r2, r1};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r3, r2, r1, r0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r1};
......
......@@ -92,38 +92,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x3: closure
// x2: object literal index
// x1: constant properties
// x0: object literal flags
Register registers[] = {x3, x2, x1, x0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x3: closure
// x2: array literal index
// x1: constant elements
Register registers[] = {x3, x2, x1};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x3: closure
// x2: object literal index
// x1: constant properties
// x0: object literal flags
Register registers[] = {x3, x2, x1, x0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x1 function the function to call
......
......@@ -634,7 +634,7 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
}
bool ObjectLiteral::IsFastCloningSupported() const {
// The FastCloneShallowObject builtin doesn't copy elements, and object
// The CreateShallowObjectLiteratal builtin doesn't copy elements, and object
// literals don't support copy-on-write (COW) elements for now.
// TODO(mvstanton): make object literals support COW elements.
return fast_elements() && is_shallow() &&
......
......@@ -1321,7 +1321,7 @@ class ObjectLiteral final : public AggregateLiteral {
// marked expressions, no store code is emitted.
void CalculateEmitStore(Zone* zone);
// Determines whether the {FastCloneShallowObject} builtin can be used.
// Determines whether the {CreateShallowObjectLiteratal} builtin can be used.
bool IsFastCloningSupported() const;
// Assemble bitfield of flags for the CreateObjectLiteral helper.
......@@ -1449,7 +1449,7 @@ class ArrayLiteral final : public AggregateLiteral {
// Populate the constant elements fixed array.
void BuildConstantElements(Isolate* isolate);
// Determines whether the {FastCloneShallowArray} builtin can be used.
// Determines whether the {CreateShallowArrayLiteral} builtin can be used.
bool IsFastCloningSupported() const;
// Assemble bitfield of flags for the CreateArrayLiteral helper.
......
This diff is collapsed.
......@@ -20,19 +20,17 @@ class ConstructorBuiltinsAssembler : public CodeStubAssembler {
Node* EmitFastNewFunctionContext(Node* closure, Node* slots, Node* context,
ScopeType scope_type);
Node* EmitFastCloneRegExp(Node* closure, Node* literal_index, Node* pattern,
Node* flags, Node* context);
Node* EmitFastCloneShallowArray(Node* closure, Node* literal_index,
Node* context, Label* call_runtime,
AllocationSiteMode allocation_site_mode);
Node* EmitCreateRegExpLiteral(Node* feedback_vector, Node* slot,
Node* pattern, Node* flags, Node* context);
Node* EmitCreateShallowArrayLiteral(Node* feedback_vector, Node* slot,
Node* context, Label* call_runtime,
AllocationSiteMode allocation_site_mode);
Node* EmitCreateEmptyArrayLiteral(Node* closure, Node* iteral_index,
Node* EmitCreateEmptyArrayLiteral(Node* feedback_vector, Node* slot,
Node* context);
void CreateFastCloneShallowArrayBuiltin(
AllocationSiteMode allocation_site_mode);
Node* EmitFastCloneShallowObject(Label* call_runtime, Node* closure,
Node* literals_index);
Node* EmitCreateShallowObjectLiteral(Node* feedback_vector, Node* slot,
Label* call_runtime);
Node* EmitCreateEmptyObjectLiteral(Node* context);
Node* EmitFastNewObject(Node* context, Node* target, Node* new_target);
......
......@@ -73,12 +73,11 @@ namespace internal {
TFC(FastNewClosure, FastNewClosure, 1) \
TFC(FastNewFunctionContextEval, FastNewFunctionContext, 1) \
TFC(FastNewFunctionContextFunction, FastNewFunctionContext, 1) \
TFC(FastCloneRegExp, FastCloneRegExp, 1) \
TFC(FastCloneShallowArrayTrack, FastCloneShallowArray, 1) \
TFC(FastCloneShallowArrayDontTrack, FastCloneShallowArray, 1) \
TFS(CreateEmptyArrayLiteral, kClosure, kLiteralIndex) \
TFS(CreateEmptyObjectLiteral, kClosure) \
TFC(FastCloneShallowObject, FastCloneShallowObject, 1) \
TFS(CreateRegExpLiteral, kFeedbackVector, kSlot, kPattern, kFlags) \
TFS(CreateEmptyArrayLiteral, kFeedbackVector, kSlot) \
TFS(CreateShallowArrayLiteral, kFeedbackVector, kSlot, kConstantElements) \
TFS(CreateShallowObjectLiteral, kFeedbackVector, kSlot, \
kBoilerplateDescription, kFlags) \
/* ES6 section 9.5.14 [[Construct]] ( argumentsList, newTarget) */ \
TFC(ConstructProxy, ConstructTrampoline, 1) \
\
......
......@@ -113,19 +113,6 @@ Handle<Code> Builtins::NewFunctionContext(ScopeType scope_type) {
return Handle<Code>::null();
}
Handle<Code> Builtins::NewCloneShallowArray(
AllocationSiteMode allocation_mode) {
switch (allocation_mode) {
case TRACK_ALLOCATION_SITE:
return builtin_handle(kFastCloneShallowArrayTrack);
case DONT_TRACK_ALLOCATION_SITE:
return builtin_handle(kFastCloneShallowArrayDontTrack);
default:
UNREACHABLE();
}
return Handle<Code>::null();
}
Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) {
switch (hint) {
case ToPrimitiveHint::kDefault:
......
......@@ -68,7 +68,6 @@ class Builtins {
InterpreterPushArgsMode mode);
Handle<Code> InterpreterPushArgsThenConstruct(InterpreterPushArgsMode mode);
Handle<Code> NewFunctionContext(ScopeType scope_type);
Handle<Code> NewCloneShallowArray(AllocationSiteMode allocation_mode);
Handle<Code> JSConstructStubGeneric();
// Used by BuiltinDeserializer.
......
......@@ -202,13 +202,6 @@ Callable CodeFactory::HandleDebuggerStatement(Isolate* isolate) {
ContextOnlyDescriptor(isolate));
}
// static
Callable CodeFactory::FastCloneShallowArray(
Isolate* isolate, AllocationSiteMode allocation_mode) {
return Callable(isolate->builtins()->NewCloneShallowArray(allocation_mode),
FastCloneShallowArrayDescriptor(isolate));
}
// static
Callable CodeFactory::FastNewFunctionContext(Isolate* isolate,
ScopeType scope_type) {
......
......@@ -60,9 +60,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable StringCompare(Isolate* isolate, Token::Value token);
static Callable SubString(Isolate* isolate);
static Callable FastCloneShallowArray(Isolate* isolate,
AllocationSiteMode allocation_mode);
static Callable FastNewFunctionContext(Isolate* isolate,
ScopeType scope_type);
......
......@@ -1480,11 +1480,11 @@ void BytecodeGraphBuilder::VisitCreateRestParameter() {
void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
Handle<String> constant_pattern =
Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
int literal_index = bytecode_iterator().GetIndexOperand(1);
int const slot_id = bytecode_iterator().GetIndexOperand(1);
VectorSlotPair pair = CreateVectorSlotPair(slot_id);
int literal_flags = bytecode_iterator().GetFlagOperand(2);
Node* literal = NewNode(javascript()->CreateLiteralRegExp(
constant_pattern, literal_flags, literal_index),
GetFunctionClosure());
Node* literal = NewNode(
javascript()->CreateLiteralRegExp(constant_pattern, pair, literal_flags));
environment()->BindAccumulator(literal, Environment::kAttachFrameState);
}
......@@ -1492,7 +1492,8 @@ void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
Handle<ConstantElementsPair> constant_elements =
Handle<ConstantElementsPair>::cast(
bytecode_iterator().GetConstantForIndexOperand(0));
int literal_index = bytecode_iterator().GetIndexOperand(1);
int const slot_id = bytecode_iterator().GetIndexOperand(1);
VectorSlotPair pair = CreateVectorSlotPair(slot_id);
int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
int literal_flags =
interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
......@@ -1504,17 +1505,15 @@ void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
// TODO(mstarzinger): Thread through number of elements. The below number is
// only an estimate and does not match {ArrayLiteral::values::length}.
int number_of_elements = constant_elements->constant_values()->length();
Node* literal = NewNode(
javascript()->CreateLiteralArray(constant_elements, literal_flags,
literal_index, number_of_elements),
GetFunctionClosure());
Node* literal = NewNode(javascript()->CreateLiteralArray(
constant_elements, pair, literal_flags, number_of_elements));
environment()->BindAccumulator(literal, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
int literal_index = bytecode_iterator().GetIndexOperand(0);
Node* literal = NewNode(javascript()->CreateEmptyLiteralArray(literal_index),
GetFunctionClosure());
int const slot_id = bytecode_iterator().GetIndexOperand(0);
VectorSlotPair pair = CreateVectorSlotPair(slot_id);
Node* literal = NewNode(javascript()->CreateEmptyLiteralArray(pair));
environment()->BindAccumulator(literal);
}
......@@ -1522,17 +1521,16 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
Handle<BoilerplateDescription> constant_properties =
Handle<BoilerplateDescription>::cast(
bytecode_iterator().GetConstantForIndexOperand(0));
int literal_index = bytecode_iterator().GetIndexOperand(1);
int const slot_id = bytecode_iterator().GetIndexOperand(1);
VectorSlotPair pair = CreateVectorSlotPair(slot_id);
int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
int literal_flags =
interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
// TODO(mstarzinger): Thread through number of properties. The below number is
// only an estimate and does not match {ObjectLiteral::properties_count}.
int number_of_properties = constant_properties->size();
Node* literal = NewNode(
javascript()->CreateLiteralObject(constant_properties, literal_flags,
literal_index, number_of_properties),
GetFunctionClosure());
Node* literal = NewNode(javascript()->CreateLiteralObject(
constant_properties, pair, literal_flags, number_of_properties));
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3),
literal, Environment::kAttachFrameState);
}
......
......@@ -854,41 +854,35 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Handle<FeedbackVector> feedback_vector;
if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) {
FeedbackSlot slot(FeedbackVector::ToSlot(p.index()));
Handle<Object> literal(feedback_vector->Get(slot), isolate());
if (literal->IsAllocationSite()) {
Handle<AllocationSite> site = Handle<AllocationSite>::cast(literal);
Handle<JSObject> boilerplate(site->boilerplate(), isolate());
int max_properties = kMaxFastLiteralProperties;
if (IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) {
AllocationSiteUsageContext site_context(isolate(), site, false);
site_context.EnterNewScope();
Node* value = effect =
AllocateFastLiteral(effect, control, boilerplate, &site_context);
site_context.ExitScope(site, boilerplate);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
Handle<Object> feedback(p.feedback().vector()->Get(p.feedback().slot()),
isolate());
if (feedback->IsAllocationSite()) {
Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback);
Handle<JSObject> boilerplate(site->boilerplate(), isolate());
int max_properties = kMaxFastLiteralProperties;
if (IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) {
AllocationSiteUsageContext site_context(isolate(), site, false);
site_context.EnterNewScope();
Node* value = effect =
AllocateFastLiteral(effect, control, boilerplate, &site_context);
site_context.ExitScope(site, boilerplate);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
}
return NoChange();
}
Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kJSCreateEmptyLiteralArray);
int literal_index = OpParameter<int>(node);
Handle<FeedbackVector> feedback_vector;
if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) {
FeedbackSlot slot(FeedbackVector::ToSlot(literal_index));
Handle<Object> raw_site(feedback_vector->Get(slot), isolate());
if (raw_site->IsAllocationSite()) {
Handle<AllocationSite> site = Handle<AllocationSite>::cast(raw_site);
DCHECK(!site->PointsToLiteral());
Node* length = jsgraph()->ZeroConstant();
return ReduceNewArray(node, length, 0, site);
}
DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
FeedbackParameter const& p = FeedbackParameterOf(node->op());
Handle<Object> feedback(p.feedback().vector()->Get(p.feedback().slot()),
isolate());
if (feedback->IsAllocationSite()) {
Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback);
DCHECK(!site->PointsToLiteral());
Node* length = jsgraph()->ZeroConstant();
return ReduceNewArray(node, length, 0, site);
}
return NoChange();
}
......@@ -930,16 +924,13 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Handle<FeedbackVector> feedback_vector;
if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) {
FeedbackSlot slot(FeedbackVector::ToSlot(p.index()));
Handle<Object> maybe_boilerplate(feedback_vector->Get(slot), isolate());
if (maybe_boilerplate->IsJSRegExp()) {
Node* value = effect = AllocateLiteralRegExp(
effect, control, Handle<JSRegExp>::cast(maybe_boilerplate));
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
Handle<Object> feedback(p.feedback().vector()->Get(p.feedback().slot()),
isolate());
if (feedback->IsJSRegExp()) {
Handle<JSRegExp> boilerplate = Handle<JSRegExp>::cast(feedback);
Node* value = effect = AllocateLiteralRegExp(effect, control, boilerplate);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
return NoChange();
}
......@@ -1505,30 +1496,6 @@ Node* JSCreateLowering::AllocateLiteralRegExp(Node* effect, Node* control,
return builder.Finish();
}
MaybeHandle<FeedbackVector> JSCreateLowering::GetSpecializationFeedbackVector(
Node* node) {
Node* const closure = NodeProperties::GetValueInput(node, 0);
switch (closure->opcode()) {
case IrOpcode::kHeapConstant: {
Handle<HeapObject> object = OpParameter<Handle<HeapObject>>(closure);
return handle(Handle<JSFunction>::cast(object)->feedback_vector());
}
case IrOpcode::kParameter: {
int const index = ParameterIndexOf(closure->op());
// The closure is always the last parameter to a JavaScript function, and
// {Parameter} indices start at -1, so value outputs of {Start} look like
// this: closure, receiver, param0, ..., paramN, context.
if (index == -1) {
return feedback_vector_;
}
break;
}
default:
break;
}
return MaybeHandle<FeedbackVector>();
}
Factory* JSCreateLowering::factory() const { return isolate()->factory(); }
Graph* JSCreateLowering::graph() const { return jsgraph()->graph(); }
......
......@@ -34,12 +34,10 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
public:
JSCreateLowering(Editor* editor, CompilationDependencies* dependencies,
JSGraph* jsgraph,
MaybeHandle<FeedbackVector> feedback_vector,
Handle<Context> native_context, Zone* zone)
: AdvancedReducer(editor),
dependencies_(dependencies),
jsgraph_(jsgraph),
feedback_vector_(feedback_vector),
native_context_(native_context),
zone_(zone) {}
~JSCreateLowering() final {}
......@@ -99,9 +97,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
Reduction ReduceNewArrayToStubCall(Node* node, Handle<AllocationSite> site);
// Infers the FeedbackVector to use for a given {node}.
MaybeHandle<FeedbackVector> GetSpecializationFeedbackVector(Node* node);
Factory* factory() const;
Graph* graph() const;
JSGraph* jsgraph() const { return jsgraph_; }
......@@ -114,7 +109,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
CompilationDependencies* const dependencies_;
JSGraph* const jsgraph_;
MaybeHandle<FeedbackVector> const feedback_vector_;
Handle<Context> const native_context_;
Zone* const zone_;
};
......
......@@ -461,15 +461,16 @@ void JSGenericLowering::LowerJSCreateKeyValueArray(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
// Use the FastCloneShallowArray builtin only for shallow boilerplates without
// properties up to the number of elements that the stubs can handle.
// Use the CreateShallowArrayLiteratlr builtin only for shallow boilerplates
// without properties up to the number of elements that the stubs can handle.
if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
p.length() < ConstructorBuiltins::kMaximumClonedShallowArrayElements) {
Callable callable = CodeFactory::FastCloneShallowArray(
isolate(), DONT_TRACK_ALLOCATION_SITE);
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kCreateShallowArrayLiteral);
ReplaceWithStubCall(node, callable, flags);
} else {
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
......@@ -479,8 +480,10 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
int literal_index = OpParameter<int>(node->op());
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(literal_index));
FeedbackParameter const& p = FeedbackParameterOf(node->op());
node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
node->RemoveInput(4); // control
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kCreateEmptyArrayLiteral);
ReplaceWithStubCall(node, callable, flags);
......@@ -489,17 +492,18 @@ void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
// Use the FastCloneShallowObject builtin only for shallow boilerplates
// Use the CreateShallowObjectLiteratal builtin only for shallow boilerplates
// without elements up to the number of properties that the stubs can handle.
if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
p.length() <=
ConstructorBuiltins::kMaximumClonedShallowObjectProperties) {
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kFastCloneShallowObject);
Builtins::CallableFor(isolate(), Builtins::kCreateShallowObjectLiteral);
ReplaceWithStubCall(node, callable, flags);
} else {
ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
......@@ -507,23 +511,18 @@ void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
}
void JSGenericLowering::LowerJSCreateEmptyLiteralObject(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kCreateEmptyObjectLiteral);
ReplaceWithStubCall(node, callable, flags);
UNREACHABLE(); // Eliminated in typed lowering.
}
void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kFastCloneRegExp);
Node* literal_index = jsgraph()->SmiConstant(p.index());
Node* literal_flags = jsgraph()->SmiConstant(p.flags());
Node* pattern = jsgraph()->HeapConstant(p.constant());
node->InsertInput(graph()->zone(), 1, literal_index);
node->InsertInput(graph()->zone(), 2, pattern);
node->InsertInput(graph()->zone(), 3, literal_flags);
Builtins::CallableFor(isolate(), Builtins::kCreateRegExpLiteral);
node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
ReplaceWithStubCall(node, callable, flags);
}
......
......@@ -290,7 +290,8 @@ std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) {
}
FeedbackParameter const& FeedbackParameterOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, op->opcode());
DCHECK(op->opcode() == IrOpcode::kJSCreateEmptyLiteralArray ||
op->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral);
return OpParameter<FeedbackParameter>(op);
}
......@@ -484,8 +485,8 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
bool operator==(CreateLiteralParameters const& lhs,
CreateLiteralParameters const& rhs) {
return lhs.constant().location() == rhs.constant().location() &&
lhs.length() == rhs.length() && lhs.flags() == rhs.flags() &&
lhs.index() == rhs.index();
lhs.feedback() == rhs.feedback() && lhs.length() == rhs.length() &&
lhs.flags() == rhs.flags();
}
......@@ -496,14 +497,13 @@ bool operator!=(CreateLiteralParameters const& lhs,
size_t hash_value(CreateLiteralParameters const& p) {
return base::hash_combine(p.constant().location(), p.length(), p.flags(),
p.index());
return base::hash_combine(p.constant().location(), p.feedback(), p.length(),
p.flags());
}
std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags()
<< ", " << p.index();
return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags();
}
......@@ -1049,36 +1049,41 @@ const Operator* JSOperatorBuilder::CreateClosure(
}
const Operator* JSOperatorBuilder::CreateLiteralArray(
Handle<ConstantElementsPair> constant_elements, int literal_flags,
int literal_index, int number_of_elements) {
CreateLiteralParameters parameters(constant_elements, number_of_elements,
literal_flags, literal_index);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties, // opcode
"JSCreateLiteralArray", // name
1, 1, 1, 1, 1, 2, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::CreateEmptyLiteralArray(int literal_index) {
return new (zone()) Operator1<int>( // --
IrOpcode::kJSCreateEmptyLiteralArray, // opcode
Operator::kNoProperties, // properties
"JSCreateEmptyLiteralArray", // name
1, 1, 1, 1, 1, 2, // counts
literal_index); // parameter
Handle<ConstantElementsPair> constant_elements,
VectorSlotPair const& feedback, int literal_flags, int number_of_elements) {
CreateLiteralParameters parameters(constant_elements, feedback,
number_of_elements, literal_flags);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralArray, // opcode
Operator::kNoProperties, // properties
"JSCreateLiteralArray", // name
0, 1, 1, 1, 1, 2, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::CreateEmptyLiteralArray(
VectorSlotPair const& feedback) {
FeedbackParameter parameters(feedback);
return new (zone()) Operator1<FeedbackParameter>( // --
IrOpcode::kJSCreateEmptyLiteralArray, // opcode
Operator::kEliminatable, // properties
"JSCreateEmptyLiteralArray", // name
0, 1, 1, 1, 1, 0, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::CreateLiteralObject(
Handle<BoilerplateDescription> constant_properties, int literal_flags,
int literal_index, int number_of_properties) {
CreateLiteralParameters parameters(constant_properties, number_of_properties,
literal_flags, literal_index);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties, // opcode
"JSCreateLiteralObject", // name
1, 1, 1, 1, 1, 2, // counts
parameters); // parameter
Handle<BoilerplateDescription> constant_properties,
VectorSlotPair const& feedback, int literal_flags,
int number_of_properties) {
CreateLiteralParameters parameters(constant_properties, feedback,
number_of_properties, literal_flags);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralObject, // opcode
Operator::kNoProperties, // properties
"JSCreateLiteralObject", // name
0, 1, 1, 1, 1, 2, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() {
......@@ -1090,14 +1095,16 @@ const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() {
}
const Operator* JSOperatorBuilder::CreateLiteralRegExp(
Handle<String> constant_pattern, int literal_flags, int literal_index) {
CreateLiteralParameters parameters(constant_pattern, -1, literal_flags,
literal_index);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties, // opcode
"JSCreateLiteralRegExp", // name
1, 1, 1, 1, 1, 2, // counts
parameters); // parameter
Handle<String> constant_pattern, VectorSlotPair const& feedback,
int literal_flags) {
CreateLiteralParameters parameters(constant_pattern, feedback, -1,
literal_flags);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralRegExp, // opcode
Operator::kNoProperties, // properties
"JSCreateLiteralRegExp", // name
0, 1, 1, 1, 1, 2, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::CreateFunctionContext(int slot_count,
......
......@@ -366,8 +366,8 @@ std::ostream& operator<<(std::ostream&, StoreNamedOwnParameters const&);
const StoreNamedOwnParameters& StoreNamedOwnParametersOf(const Operator* op);
// Defines the feedback, i.e., vector and index, for storing a data property in
// an object literal. This is
// used as a parameter by the JSStoreDataPropertyInLiteral operator.
// an object literal. This is used as a parameter by JSCreateEmptyLiteralArray
// and JSStoreDataPropertyInLiteral operators.
class FeedbackParameter final {
public:
explicit FeedbackParameter(VectorSlotPair const& feedback)
......@@ -561,20 +561,23 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
// JSCreateLiteralRegExp operators.
class CreateLiteralParameters final {
public:
CreateLiteralParameters(Handle<HeapObject> constant, int length, int flags,
int index)
: constant_(constant), length_(length), flags_(flags), index_(index) {}
CreateLiteralParameters(Handle<HeapObject> constant,
VectorSlotPair const& feedback, int length, int flags)
: constant_(constant),
feedback_(feedback),
length_(length),
flags_(flags) {}
Handle<HeapObject> constant() const { return constant_; }
VectorSlotPair const& feedback() const { return feedback_; }
int length() const { return length_; }
int flags() const { return flags_; }
int index() const { return index_; }
private:
Handle<HeapObject> const constant_;
VectorSlotPair const feedback_;
int const length_;
int const flags_;
int const index_;
};
bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&);
......@@ -647,16 +650,18 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* CreateIterResultObject();
const Operator* CreateKeyValueArray();
const Operator* CreateLiteralArray(Handle<ConstantElementsPair> constant,
int literal_flags, int literal_index,
int number_of_elements);
const Operator* CreateEmptyLiteralArray(int literal_index);
VectorSlotPair const& feedback,
int literal_flags, int number_of_elements);
const Operator* CreateEmptyLiteralArray(VectorSlotPair const& feedback);
const Operator* CreateEmptyLiteralObject();
const Operator* CreateLiteralObject(Handle<BoilerplateDescription> constant,
int literal_flags, int literal_index,
VectorSlotPair const& feedback,
int literal_flags,
int number_of_properties);
const Operator* CreateLiteralRegExp(Handle<String> constant_pattern,
int literal_flags, int literal_index);
VectorSlotPair const& feedback,
int literal_flags);
const Operator* CallForwardVarargs(size_t arity, uint32_t start_index);
const Operator* Call(
......
......@@ -1028,11 +1028,9 @@ struct TypedLoweringPhase {
JSBuiltinReducer builtin_reducer(
&graph_reducer, data->jsgraph(),
data->info()->dependencies(), data->native_context());
Handle<FeedbackVector> feedback_vector(
data->info()->closure()->feedback_vector());
JSCreateLowering create_lowering(
&graph_reducer, data->info()->dependencies(), data->jsgraph(),
feedback_vector, data->native_context(), temp_zone);
data->native_context(), temp_zone);
JSTypedLowering typed_lowering(&graph_reducer, data->jsgraph(), temp_zone);
TypedOptimization typed_optimization(
&graph_reducer, data->info()->dependencies(), data->jsgraph());
......
......@@ -90,27 +90,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {edi, eax, ecx, edx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {eax, ebx, ecx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {eax, ebx, ecx, edx};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {edi};
......
......@@ -400,26 +400,6 @@ void NewArgumentsElementsDescriptor::InitializePlatformSpecific(
DefaultInitializePlatformSpecific(data, 3);
}
void FastCloneRegExpDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kClosure, kLiteralIndex, kPattern, kFlags
MachineType machine_types[] = {
MachineType::AnyTagged(), MachineType::TaggedSigned(),
MachineType::AnyTagged(), MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void FastCloneShallowArrayDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kClosure, kLiteralIndex, kConstantElements
MachineType machine_types[] = {MachineType::AnyTagged(),
MachineType::TaggedSigned(),
MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void CallTrampolineDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kFunction, kActualArgumentsCount
......
......@@ -37,9 +37,6 @@ class PlatformInterfaceDescriptor;
V(TypeConversion) \
V(TypeConversionStackParameter) \
V(Typeof) \
V(FastCloneRegExp) \
V(FastCloneShallowArray) \
V(FastCloneShallowObject) \
V(CallFunction) \
V(CallVarargs) \
V(CallForwardVarargs) \
......@@ -560,29 +557,6 @@ class TypeofDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
};
class FastCloneRegExpDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kClosure, kLiteralIndex, kPattern, kFlags)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneRegExpDescriptor,
CallInterfaceDescriptor)
};
class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kClosure, kLiteralIndex, kConstantElements)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneShallowArrayDescriptor,
CallInterfaceDescriptor)
};
class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kClosure, kLiteralIndex, kBoilerplateDescription, kFlags)
DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
};
class CallTrampolineDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kFunction, kActualArgumentsCount)
......
......@@ -1933,7 +1933,7 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
object_literals_.push_back(std::make_pair(expr, entry));
}
// TODO(cbruni): Directly generate runtime call for literals we cannot
// optimize once the FastCloneShallowObject stub is in sync with the TF
// optimize once the CreateShallowObjectLiteral stub is in sync with the TF
// optimizations.
builder()->CreateObjectLiteral(entry, literal_index, flags, literal);
......
......@@ -2643,15 +2643,15 @@ IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) {
// Creates a regular expression literal for literal index <literal_idx> with
// <flags> and the pattern in <pattern_idx>.
IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) {
Node* index = BytecodeOperandIdx(0);
Node* pattern = LoadConstantPoolEntry(index);
Node* literal_index = BytecodeOperandIdxSmi(1);
Node* pattern_index = BytecodeOperandIdx(0);
Node* pattern = LoadConstantPoolEntry(pattern_index);
Node* feedback_vector = LoadFeedbackVector();
Node* slot_id = BytecodeOperandIdx(1);
Node* flags = SmiFromWord32(BytecodeOperandFlag(2));
Node* closure = LoadRegister(Register::function_closure());
Node* context = GetContext();
ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitFastCloneRegExp(
closure, literal_index, pattern, flags, context);
Node* result = constructor_assembler.EmitCreateRegExpLiteral(
feedback_vector, slot_id, pattern, flags, context);
SetAccumulator(result);
Dispatch();
}
......@@ -2661,8 +2661,8 @@ IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) {
// Creates an array literal for literal index <literal_idx> with
// CreateArrayLiteral flags <flags> and constant elements in <element_idx>.
IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
Node* literal_index = BytecodeOperandIdxSmi(1);
Node* closure = LoadRegister(Register::function_closure());
Node* feedback_vector = LoadFeedbackVector();
Node* slot_id = BytecodeOperandIdx(1);
Node* context = GetContext();
Node* bytecode_flags = BytecodeOperandFlag(2);
......@@ -2674,8 +2674,9 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
BIND(&fast_shallow_clone);
{
ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitFastCloneShallowArray(
closure, literal_index, context, &call_runtime, TRACK_ALLOCATION_SITE);
Node* result = constructor_assembler.EmitCreateShallowArrayLiteral(
feedback_vector, slot_id, context, &call_runtime,
TRACK_ALLOCATION_SITE);
SetAccumulator(result);
Dispatch();
}
......@@ -2687,8 +2688,9 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
Node* flags = SmiTag(flags_raw);
Node* index = BytecodeOperandIdx(0);
Node* constant_elements = LoadConstantPoolEntry(index);
Node* result = CallRuntime(Runtime::kCreateArrayLiteral, context, closure,
literal_index, constant_elements, flags);
Node* result =
CallRuntime(Runtime::kCreateArrayLiteral, context, feedback_vector,
SmiTag(slot_id), constant_elements, flags);
SetAccumulator(result);
Dispatch();
}
......@@ -2698,12 +2700,12 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
//
// Creates an empty JSArray literal for literal index <literal_idx>.
IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) {
Node* literal_index = BytecodeOperandIdxSmi(0);
Node* closure = LoadRegister(Register::function_closure());
Node* feedback_vector = LoadFeedbackVector();
Node* slot_id = BytecodeOperandIdx(0);
Node* context = GetContext();
ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitCreateEmptyArrayLiteral(
closure, literal_index, context);
feedback_vector, slot_id, context);
SetAccumulator(result);
Dispatch();
}
......@@ -2713,9 +2715,9 @@ IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) {
// Creates an object literal for literal index <literal_idx> with
// CreateObjectLiteralFlags <flags> and constant elements in <element_idx>.
IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
Node* literal_index = BytecodeOperandIdxSmi(1);
Node* feedback_vector = LoadFeedbackVector();
Node* slot_id = BytecodeOperandIdx(1);
Node* bytecode_flags = BytecodeOperandFlag(2);
Node* closure = LoadRegister(Register::function_closure());
// Check if we can do a fast clone or have to call the runtime.
Label if_fast_clone(this), if_not_fast_clone(this, Label::kDeferred);
......@@ -2725,10 +2727,10 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
BIND(&if_fast_clone);
{
// If we can do a fast clone do the fast-path in FastCloneShallowObjectStub.
// If we can do a fast clone do the fast-path in CreateShallowObjectLiteral.
ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitFastCloneShallowObject(
&if_not_fast_clone, closure, literal_index);
Node* result = constructor_assembler.EmitCreateShallowObjectLiteral(
feedback_vector, slot_id, &if_not_fast_clone);
StoreRegister(result, BytecodeOperandReg(3));
Dispatch();
}
......@@ -2744,8 +2746,9 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
bytecode_flags);
Node* flags = SmiTag(flags_raw);
Node* result = CallRuntime(Runtime::kCreateObjectLiteral, context, closure,
literal_index, boilerplate_description, flags);
Node* result =
CallRuntime(Runtime::kCreateObjectLiteral, context, feedback_vector,
SmiTag(slot_id), boilerplate_description, flags);
StoreRegister(result, BytecodeOperandReg(3));
// TODO(klaasb) build a single dispatch once the call is inlined
Dispatch();
......
......@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1, a0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1, a0};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a1};
......
......@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1, a0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1, a0};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a1};
......
......@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r6, r5, r4, r3};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r6, r5, r4};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r6, r5, r4, r3};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r4};
......
......@@ -451,10 +451,9 @@ Handle<Object> InnerCreateBoilerplate(Isolate* isolate,
template <typename Boilerplate>
MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
Handle<JSFunction> closure,
Handle<FeedbackVector> vector,
int literals_index,
Handle<HeapObject> description, int flags) {
Handle<FeedbackVector> vector(closure->feedback_vector(), isolate);
FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index));
CHECK(literals_slot.ToInt() < vector->length());
Handle<Object> literal_site(vector->Get(literals_slot), isolate);
......@@ -521,36 +520,35 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, description, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3);
RETURN_RESULT_OR_FAILURE(
isolate, CreateLiteral<ObjectBoilerplate>(
isolate, closure, literals_index, description, flags));
isolate, CreateLiteral<ObjectBoilerplate>(isolate, vector, literals_index,
description, flags));
}
RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3);
RETURN_RESULT_OR_FAILURE(
isolate, CreateLiteral<ArrayBoilerplate>(isolate, closure, literals_index,
isolate, CreateLiteral<ArrayBoilerplate>(isolate, vector, literals_index,
elements, flags));
}
RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) {
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
CONVERT_SMI_ARG_CHECKED(index, 1);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3);
Handle<FeedbackVector> vector(closure->feedback_vector(), isolate);
FeedbackSlot literal_slot(FeedbackVector::ToSlot(index));
// Check if boilerplate exists. If not, create it first.
......
......@@ -86,24 +86,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r5, r4, r3, r2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r5, r4, r3};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r5, r4, r3, r2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r3};
......
......@@ -91,27 +91,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
// static
const Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {rdi, rax, rcx, rdx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {rax, rbx, rcx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {rax, rbx, rcx, rdx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {rdi};
......
......@@ -40,8 +40,7 @@ class JSCreateLoweringTest : public TypedGraphTest {
&machine);
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph());
JSCreateLowering reducer(&graph_reducer, &deps_, &jsgraph,
MaybeHandle<FeedbackVector>(), native_context(),
JSCreateLowering reducer(&graph_reducer, &deps_, &jsgraph, native_context(),
zone());
return reducer.Reduce(node);
}
......
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