[literals] No longer use a FeedbackVectorSlot for the empty object literal

Bug: v8:6211
Change-Id: I0f15c59b7b786ab327e4ab548523095dd85ba83e
Reviewed-on: https://chromium-review.googlesource.com/637835
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47650}
This commit is contained in:
Camillo Bruni 2017-08-28 14:48:05 +02:00 committed by Commit Bot
parent 8fb5000e86
commit dbaafb76c7
15 changed files with 21 additions and 50 deletions

View File

@ -780,8 +780,6 @@ TF_BUILTIN(FastCloneShallowObject, ConstructorBuiltinsAssembler) {
// Used by the CreateEmptyObjectLiteral stub and bytecode.
Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral(
Node* context) {
// TODO(cbruni): check whether we have to enable pretenuring support again for
// the empty object literal.
Node* native_context = LoadNativeContext(context);
Node* object_function =
LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX);
@ -796,9 +794,6 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral(
}
TF_BUILTIN(CreateEmptyObjectLiteral, ConstructorBuiltinsAssembler) {
// TODO(cbruni): remove closure and literal_index paramters once it's clear
// whether we can live without pretenuring support for the empty object
// literal.
Node* context = Parameter(Descriptor::kContext);
Node* result = EmitCreateEmptyObjectLiteral(context);
Return(result);

View File

@ -80,7 +80,7 @@ namespace internal {
TFC(FastCloneShallowArrayTrack, FastCloneShallowArray, 1) \
TFC(FastCloneShallowArrayDontTrack, FastCloneShallowArray, 1) \
TFS(CreateEmptyArrayLiteral, kClosure, kLiteralIndex) \
TFS(CreateEmptyObjectLiteral, kClosure, kLiteralIndex) \
TFS(CreateEmptyObjectLiteral, kClosure) \
TFC(FastCloneShallowObject, FastCloneShallowObject, 1) \
/* ES6 section 9.5.14 [[Construct]] ( argumentsList, newTarget) */ \
TFC(ConstructProxy, ConstructTrampoline, 1) \

View File

@ -1540,9 +1540,8 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
}
void BytecodeGraphBuilder::VisitCreateEmptyObjectLiteral() {
int literal_index = bytecode_iterator().GetIndexOperand(0);
Node* literal = NewNode(javascript()->CreateEmptyLiteralObject(literal_index),
GetFunctionClosure());
Node* literal =
NewNode(javascript()->CreateEmptyLiteralObject(), GetFunctionClosure());
environment()->BindAccumulator(literal);
}

View File

@ -940,7 +940,7 @@ Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
return NoChange();
}
Reduction JSCreateLowering::ReduceNewObject(Node* node) {
Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralObject, node->opcode());
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
@ -971,21 +971,6 @@ Reduction JSCreateLowering::ReduceNewObject(Node* node) {
return Changed(node);
}
Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kJSCreateEmptyLiteralObject);
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());
// TODO(cbruni): remove once the empty object literal doesn't rely on the
// AllocationSite anymore.
DCHECK(!raw_site->IsAllocationSite());
return ReduceNewObject(node);
}
return NoChange();
}
Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralRegExp);
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());

View File

@ -67,7 +67,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
Handle<AllocationSite> site);
Reduction ReduceNewArray(Node* node, std::vector<Node*> values,
Handle<AllocationSite> site);
Reduction ReduceNewObject(Node* node);
Node* AllocateArguments(Node* effect, Node* control, Node* frame_state);
Node* AllocateRestArguments(Node* effect, Node* control, Node* frame_state,

View File

@ -507,8 +507,6 @@ void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
void JSGenericLowering::LowerJSCreateEmptyLiteralObject(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
int literal_index = OpParameter<int>(node->op());
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(literal_index));
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kCreateEmptyObjectLiteral);
ReplaceWithStubCall(node, callable, flags);

View File

@ -1045,13 +1045,12 @@ const Operator* JSOperatorBuilder::CreateLiteralObject(
parameters); // parameter
}
const Operator* JSOperatorBuilder::CreateEmptyLiteralObject(int literal_index) {
return new (zone()) Operator1<int>( // --
const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() {
return new (zone()) Operator( // --
IrOpcode::kJSCreateEmptyLiteralObject, // opcode
Operator::kNoProperties, // properties
"JSCreateEmptyLiteralObject", // name
1, 1, 1, 1, 1, 2, // counts
literal_index); // parameter
1, 1, 1, 1, 1, 2); // counts
}
const Operator* JSOperatorBuilder::CreateLiteralRegExp(

View File

@ -637,7 +637,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
int literal_flags, int literal_index,
int number_of_elements);
const Operator* CreateEmptyLiteralArray(int literal_index);
const Operator* CreateEmptyLiteralObject(int literal_index);
const Operator* CreateEmptyLiteralObject();
const Operator* CreateLiteralObject(Handle<BoilerplateDescription> constant,
int literal_flags, int literal_index,

View File

@ -977,9 +977,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateEmptyObjectLiteral(
int literal_index) {
OutputCreateEmptyObjectLiteral(literal_index);
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateEmptyObjectLiteral() {
OutputCreateEmptyObjectLiteral();
return *this;
}

View File

@ -225,7 +225,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
BytecodeArrayBuilder& CreateObjectLiteral(size_t constant_properties_entry,
int literal_index, int flags,
Register output);
BytecodeArrayBuilder& CreateEmptyObjectLiteral(int literal_index);
BytecodeArrayBuilder& CreateEmptyObjectLiteral();
// Push the context in accumulator as the new context, and store in register
// |context|.

View File

@ -1904,16 +1904,15 @@ void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
}
void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
int literal_index = feedback_index(expr->literal_slot());
// Fast path for the empty object literal which doesn't need an
// AllocationSite.
if (expr->IsEmptyObjectLiteral()) {
DCHECK(expr->IsFastCloningSupported());
builder()->CreateEmptyObjectLiteral(literal_index);
builder()->CreateEmptyObjectLiteral();
return;
}
int literal_index = feedback_index(expr->literal_slot());
// Deep-copy the literal boilerplate.
uint8_t flags = CreateObjectLiteralFlags::Encode(
expr->ComputeFlags(), expr->IsFastCloningSupported());

View File

@ -230,7 +230,7 @@ namespace interpreter {
V(CreateEmptyArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx) \
V(CreateObjectLiteral, AccumulatorUse::kNone, OperandType::kIdx, \
OperandType::kIdx, OperandType::kFlag8, OperandType::kRegOut) \
V(CreateEmptyObjectLiteral, AccumulatorUse::kWrite, OperandType::kIdx) \
V(CreateEmptyObjectLiteral, AccumulatorUse::kWrite) \
\
/* Closure allocation */ \
V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx, \

View File

@ -2707,12 +2707,10 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
}
}
// CreateEmptyObjectLiteral <literal_idx>
// CreateEmptyObjectLiteral
//
// Creates an empty JSObject literal for literal index <literal_idx>.
// Creates an empty JSObject literal.
IGNITION_HANDLER(CreateEmptyObjectLiteral, InterpreterAssembler) {
// TODO(cbruni): remove literal_index and closure parameter once we know
// whether empty object literals work without pretenuring support.
Node* context = GetContext();
ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitCreateEmptyObjectLiteral(context);

View File

@ -11,10 +11,10 @@ snippet: "
"
frame size: 0
parameter count: 1
bytecode array length: 4
bytecode array length: 3
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateEmptyObjectLiteral), U8(0),
/* 34 S> */ B(CreateEmptyObjectLiteral),
/* 45 S> */ B(Return),
]
constant pool: [
@ -333,7 +333,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 34
bytecode array length: 33
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
@ -342,7 +342,7 @@ bytecodes: [
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), I8(1),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(2),
B(CreateEmptyObjectLiteral), U8(0),
B(CreateEmptyObjectLiteral),
B(Star), R(3),
B(Mov), R(1), R(2),
B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(2), U8(2),

View File

@ -353,7 +353,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.CreateArrayLiteral(0, 0, 0)
.CreateEmptyArrayLiteral(0)
.CreateObjectLiteral(0, 0, 0, reg)
.CreateEmptyObjectLiteral(0);
.CreateEmptyObjectLiteral();
// Emit load and store operations for module variables.
builder.LoadModuleVariable(-1, 42)