Commit 86eafdd4 authored by franzih's avatar franzih Committed by Commit bot

Add CreateDataPropertyInLiteralFlags.

Encode the PropertyAttribute and whether the function
names must be set as a flag instead of setting two registers.

BUG=v8:5624

Review-Url: https://codereview.chromium.org/2586463002
Cr-Commit-Position: refs/heads/master@{#41812}
parent 1c763e00
......@@ -781,12 +781,10 @@ void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* value =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
Node* attrs =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
int flags = bytecode_iterator().GetFlagOperand(3);
Node* set_function_name = environment()->LookupAccumulator();
const Operator* op = javascript()->StoreDataPropertyInLiteral();
Node* node = NewNode(op, object, name, value, attrs, set_function_name);
Node* node = NewNode(op, object, name, value, jsgraph()->Constant(flags));
environment()->RecordAfterState(node, Environment::kAttachFrameState);
}
......
......@@ -85,12 +85,6 @@ class BytecodeGraphBuilder {
return MakeNode(op, arraysize(buffer), buffer, false);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
Node* n5) {
Node* buffer[] = {n1, n2, n3, n4, n5};
return MakeNode(op, arraysize(buffer), buffer, false);
}
// Helpers to create new control nodes.
Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
......
......@@ -481,7 +481,7 @@ CompareOperationHint CompareOperationHintOf(const Operator* op) {
V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \
V(StackCheck, Operator::kNoWrite, 0, 0) \
V(GetSuperConstructor, Operator::kNoWrite, 1, 1) \
V(StoreDataPropertyInLiteral, Operator::kNoProperties, 5, 0)
V(StoreDataPropertyInLiteral, Operator::kNoProperties, 4, 0)
#define BINARY_OP_LIST(V) \
V(BitwiseOr) \
......
......@@ -11,6 +11,7 @@
#include <ostream>
#include "src/base/build_config.h"
#include "src/base/flags.h"
#include "src/base/logging.h"
#include "src/base/macros.h"
......@@ -1310,6 +1311,17 @@ inline std::ostream& operator<<(std::ostream& os, IterationKind kind) {
return os;
}
// Flags for the runtime function kDefineDataPropertyInLiteral. A property can
// be enumerable or not, and, in case of functions, the function name
// can be set or not.
enum class DataPropertyInLiteralFlag {
kNoFlags = 0,
kDontEnum = 1 << 0,
kSetFunctionName = 1 << 1
};
typedef base::Flags<DataPropertyInLiteralFlag> DataPropertyInLiteralFlags;
DEFINE_OPERATORS_FOR_FLAGS(DataPropertyInLiteralFlags)
} // namespace internal
} // namespace v8
......
......@@ -554,8 +554,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreDataPropertyInLiteral(
Register object, Register name, Register value, Register attrs) {
OutputStaDataPropertyInLiteral(object, name, value, attrs);
Register object, Register name, Register value,
DataPropertyInLiteralFlags flags) {
OutputStaDataPropertyInLiteral(object, name, value, flags);
return *this;
}
......
......@@ -124,10 +124,9 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
// Store properties. Flag for NeedsSetFunctionName() should
// be in the accumulator.
BytecodeArrayBuilder& StoreDataPropertyInLiteral(Register object,
Register name,
Register value,
Register attrs);
BytecodeArrayBuilder& StoreDataPropertyInLiteral(
Register object, Register name, Register value,
DataPropertyInLiteralFlags flags);
// Store properties. The value to be stored should be in the accumulator.
BytecodeArrayBuilder& StoreNamedProperty(Register object,
......
......@@ -1500,9 +1500,11 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
switch (property->kind()) {
case ClassLiteral::Property::METHOD: {
builder()
->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
.StoreDataPropertyInLiteral(receiver, key, value, attr);
DataPropertyInLiteralFlags flags = DataPropertyInLiteralFlag::kDontEnum;
if (property->NeedsSetFunctionName()) {
flags |= DataPropertyInLiteralFlag::kSetFunctionName;
}
builder()->StoreDataPropertyInLiteral(receiver, key, value, flags);
break;
}
case ClassLiteral::Property::GETTER: {
......@@ -1737,13 +1739,14 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Register value = VisitForRegisterValue(property->value());
VisitSetHomeObject(value, literal, property);
Register attr = register_allocator()->NewRegister();
DataPropertyInLiteralFlags data_property_flags =
DataPropertyInLiteralFlag::kNoFlags;
if (property->NeedsSetFunctionName()) {
data_property_flags |= DataPropertyInLiteralFlag::kSetFunctionName;
}
builder()
->LoadLiteral(Smi::FromInt(NONE))
.StoreAccumulatorInRegister(attr)
.LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
.StoreDataPropertyInLiteral(literal, key, value, attr);
builder()->StoreDataPropertyInLiteral(literal, key, value,
data_property_flags);
break;
}
case ObjectLiteral::Property::GETTER:
......
......@@ -98,8 +98,8 @@ namespace interpreter {
OperandType::kReg, OperandType::kIdx) \
V(StaKeyedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kReg, OperandType::kIdx) \
V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kReg, OperandType::kReg, OperandType::kReg) \
V(StaDataPropertyInLiteral, AccumulatorUse::kNone, OperandType::kReg, \
OperandType::kReg, OperandType::kReg, OperandType::kFlag8) \
\
/* Binary Operators */ \
V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \
......
......@@ -817,11 +817,11 @@ void Interpreter::DoStaKeyedPropertyStrict(InterpreterAssembler* assembler) {
DoKeyedStoreIC(ic, assembler);
}
// StaDataPropertyInLiteral <object> <name> <value> <attrs>
// StaDataPropertyInLiteral <object> <name> <value> <flags>
//
// Define a property <name> with value <value> in <object>. Use property
// attributes <attrs> in the definition and set the name property of <value>
// according to the flag in the accumulator.
// Define a property <name> with value <value> in <object>. Property attributes
// and whether set_function_name are stored in DataPropertyInLiteralFlags
// <flags>.
//
// This definition is not observable and is used only for definitions
// in object or class literals.
......@@ -832,15 +832,12 @@ void Interpreter::DoStaDataPropertyInLiteral(InterpreterAssembler* assembler) {
Node* name = __ LoadRegister(name_reg_index);
Node* value_reg_index = __ BytecodeOperandReg(2);
Node* value = __ LoadRegister(value_reg_index);
Node* attrs_reg_index = __ BytecodeOperandReg(3);
Node* attrs = __ LoadRegister(attrs_reg_index);
Node* set_function_name = __ GetAccumulator();
Node* flags = __ SmiFromWord32(__ BytecodeOperandFlag(3));
Node* context = __ GetContext();
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral, context, object, name,
value, attrs, set_function_name);
value, flags);
__ Dispatch();
}
......
......@@ -648,14 +648,20 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
HandleScope scope(isolate);
DCHECK(args.length() == 5);
DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
CONVERT_SMI_ARG_CHECKED(set_function_name, 4);
CONVERT_SMI_ARG_CHECKED(flag, 3);
DataPropertyInLiteralFlags flags =
static_cast<DataPropertyInLiteralFlag>(flag);
PropertyAttributes attrs = (flags & DataPropertyInLiteralFlag::kDontEnum)
? PropertyAttributes::DONT_ENUM
: PropertyAttributes::NONE;
if (set_function_name) {
if (flags & DataPropertyInLiteralFlag::kSetFunctionName) {
DCHECK(value->IsJSFunction());
JSFunction::SetName(Handle<JSFunction>::cast(value), name,
isolate->factory()->empty_string());
......
......@@ -412,7 +412,7 @@ namespace internal {
F(TryMigrateInstance, 1, 1) \
F(IsJSGlobalProxy, 1, 1) \
F(DefineAccessorPropertyUnchecked, 5, 1) \
F(DefineDataPropertyInLiteral, 5, 1) \
F(DefineDataPropertyInLiteral, 4, 1) \
F(GetDataProperty, 2, 1) \
F(GetConstructorName, 1, 1) \
F(HasFastPackedElements, 1, 1) \
......
......@@ -12,9 +12,9 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 9
frame size: 8
parameter count: 1
bytecode array length: 75
bytecode array length: 72
bytecodes: [
B(LdaTheHole),
B(Star), R(2),
......@@ -38,9 +38,7 @@ bytecodes: [
B(CreateClosure), U8(3), U8(2),
B(Star), R(7),
B(LdaSmi), U8(2),
B(Star), R(8),
B(LdaZero),
B(StaDataPropertyInLiteral), R(4), R(6), R(7), R(8),
B(StaDataPropertyInLiteral), R(4), R(6), R(7), U8(1),
B(CallRuntime), U16(Runtime::kInstallClassNameAccessor), R(3), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(Star), R(0),
......@@ -65,9 +63,9 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 9
frame size: 8
parameter count: 1
bytecode array length: 75
bytecode array length: 72
bytecodes: [
B(LdaTheHole),
B(Star), R(2),
......@@ -91,9 +89,7 @@ bytecodes: [
B(CreateClosure), U8(3), U8(2),
B(Star), R(7),
B(LdaSmi), U8(2),
B(Star), R(8),
B(LdaZero),
B(StaDataPropertyInLiteral), R(4), R(6), R(7), R(8),
B(StaDataPropertyInLiteral), R(4), R(6), R(7), U8(1),
B(CallRuntime), U16(Runtime::kInstallClassNameAccessor), R(3), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(Star), R(0),
......@@ -122,7 +118,7 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 119
bytecode array length: 115
bytecodes: [
B(CreateFunctionContext), U8(2),
B(PushContext), R(3),
......@@ -152,9 +148,8 @@ bytecodes: [
B(CreateClosure), U8(4), U8(2),
B(Star), R(8),
B(LdaSmi), U8(2),
B(StaDataPropertyInLiteral), R(5), R(7), R(8), U8(3),
B(Star), R(9),
B(LdaSmi), U8(1),
B(StaDataPropertyInLiteral), R(5), R(7), R(8), R(9),
B(LdaCurrentContextSlot), U8(5),
/* 106 E> */ B(ToName), R(7),
B(LdaConstant), U8(3),
......@@ -164,8 +159,7 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(CreateClosure), U8(5), U8(2),
B(Star), R(8),
B(LdaSmi), U8(1),
B(StaDataPropertyInLiteral), R(6), R(7), R(8), R(9),
B(StaDataPropertyInLiteral), R(6), R(7), R(8), U8(3),
B(CallRuntime), U16(Runtime::kInstallClassNameAccessorWithCheck), R(4), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
B(Star), R(0),
......@@ -237,9 +231,9 @@ snippet: "
(class {})
class E { static name () {}}
"
frame size: 10
frame size: 9
parameter count: 1
bytecode array length: 104
bytecode array length: 101
bytecodes: [
B(LdaTheHole),
B(Star), R(3),
......@@ -277,9 +271,7 @@ bytecodes: [
B(CreateClosure), U8(4), U8(2),
B(Star), R(8),
B(LdaSmi), U8(2),
B(Star), R(9),
B(LdaZero),
B(StaDataPropertyInLiteral), R(4), R(7), R(8), R(9),
B(StaDataPropertyInLiteral), R(4), R(7), R(8), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
B(Star), R(0),
B(Star), R(2),
......
......@@ -285,9 +285,9 @@ handlers: [
snippet: "
var a = 'test'; return { [a]: 1 };
"
frame size: 5
frame size: 4
parameter count: 1
bytecode array length: 28
bytecode array length: 24
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
......@@ -296,10 +296,7 @@ bytecodes: [
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), R(4),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), U8(0),
B(Ldar), R(1),
/* 69 S> */ B(Return),
]
......@@ -314,9 +311,9 @@ handlers: [
snippet: "
var a = 'test'; return { val: a, [a]: 1 };
"
frame size: 5
frame size: 4
parameter count: 1
bytecode array length: 32
bytecode array length: 28
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
......@@ -326,10 +323,7 @@ bytecodes: [
/* 68 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), R(4),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), U8(0),
B(Ldar), R(1),
/* 77 S> */ B(Return),
]
......@@ -347,7 +341,7 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 44
bytecode array length: 40
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
......@@ -356,10 +350,7 @@ bytecodes: [
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), R(4),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), U8(0),
B(CreateObjectLiteral), U8(1), U8(0), U8(35), R(4),
B(Mov), R(1), R(2),
B(Mov), R(4), R(3),
......@@ -380,7 +371,7 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 65
bytecode array length: 61
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
......@@ -389,10 +380,7 @@ bytecodes: [
/* 60 E> */ B(ToName), R(2),
B(LdaConstant), U8(2),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), R(4),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), U8(0),
B(LdaConstant), U8(3),
B(ToName), R(3),
B(CreateClosure), U8(4), U8(2),
......
......@@ -323,7 +323,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreNamedProperty(reg, wide_name, 0, LanguageMode::STRICT)
.StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
builder.StoreDataPropertyInLiteral(reg, reg, reg, reg);
builder.StoreDataPropertyInLiteral(reg, reg, reg,
DataPropertyInLiteralFlag::kNoFlags);
// Emit wide context operations.
builder.LoadContextSlot(reg, 1024, 0).StoreContextSlot(reg, 1024, 0);
......
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