Commit 81736c71 authored by franzih's avatar franzih Committed by Commit bot

[runtime] Collect IC feedback in DefineDataPropertyInLiteral.

Add a feedback vector slot for computed property names in object
and class literals. Introduce new slot kind for storing
computed property names.

Change StaDataPropertyInLiteral to use the accumulator (again), so
we don't exceed Bytecodes::kMaxOperands.

We assume that most computed property names are
symbols. Therefore we should see performance
improvements, even if we deal with monomorphic ICs only.

This CL only collects feedback but does not use
it in Reduce() yet.

BUG=v8:5624

Review-Url: https://codereview.chromium.org/2587393006
Cr-Commit-Position: refs/heads/master@{#42082}
parent c4e0b159
......@@ -349,6 +349,16 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory,
}
}
FeedbackVectorSlot LiteralProperty::GetStoreDataPropertySlot() const {
int offset = FunctionLiteral::NeedsHomeObject(value_) ? 1 : 0;
return GetSlot(offset);
}
void LiteralProperty::SetStoreDataPropertySlot(FeedbackVectorSlot slot) {
int offset = FunctionLiteral::NeedsHomeObject(value_) ? 1 : 0;
return SetSlot(slot, offset);
}
bool LiteralProperty::NeedsSetFunctionName() const {
return is_computed_name_ &&
(value_->IsAnonymousFunctionDefinition() ||
......@@ -382,6 +392,8 @@ void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
if (FunctionLiteral::NeedsHomeObject(value)) {
property->SetSlot(spec->AddStoreICSlot());
}
property->SetStoreDataPropertySlot(
spec->AddStoreDataPropertyInLiteralICSlot());
}
}
......@@ -456,6 +468,8 @@ void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
property->SetSlot(spec->AddStoreICSlot());
}
}
property->SetStoreDataPropertySlot(
spec->AddStoreDataPropertyInLiteralICSlot());
}
}
......
......@@ -1328,11 +1328,15 @@ class LiteralProperty : public ZoneObject {
return slots_[offset];
}
FeedbackVectorSlot GetStoreDataPropertySlot() const;
void SetSlot(FeedbackVectorSlot slot, int offset = 0) {
DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
slots_[offset] = slot;
}
void SetStoreDataPropertySlot(FeedbackVectorSlot slot);
bool NeedsSetFunctionName() const;
protected:
......
......@@ -779,11 +779,12 @@ void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* name =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* value =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
int flags = bytecode_iterator().GetFlagOperand(3);
Node* value = environment()->LookupAccumulator();
int flags = bytecode_iterator().GetFlagOperand(2);
VectorSlotPair feedback =
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
const Operator* op = javascript()->StoreDataPropertyInLiteral();
const Operator* op = javascript()->StoreDataPropertyInLiteral(feedback);
Node* node = NewNode(op, object, name, value, jsgraph()->Constant(flags));
environment()->RecordAfterState(node, Environment::kAttachFrameState);
}
......
......@@ -495,11 +495,11 @@ Node* CodeAssembler::CallRuntime(Runtime::FunctionId function, Node* context,
return return_value;
}
// Instantiate CallRuntime() with up to 5 arguments.
// Instantiate CallRuntime() with up to 6 arguments.
#define INSTANTIATE(...) \
template V8_EXPORT_PRIVATE Node* CodeAssembler::CallRuntime( \
Runtime::FunctionId, __VA_ARGS__);
REPEAT_1_TO_6(INSTANTIATE, Node*)
REPEAT_1_TO_7(INSTANTIATE, Node*)
#undef INSTANTIATE
template <class... TArgs>
......
......@@ -264,6 +264,10 @@ void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
}
void JSGenericLowering::LowerJSStoreDataPropertyInLiteral(Node* node) {
DataPropertyParameters const& p = DataPropertyParametersOf(node->op());
node->InsertInputs(zone(), 4, 2);
node->ReplaceInput(4, jsgraph()->HeapConstant(p.feedback().vector()));
node->ReplaceInput(5, jsgraph()->SmiConstant(p.feedback().index()));
ReplaceWithRuntimeCall(node, Runtime::kDefineDataPropertyInLiteral);
}
......
......@@ -83,6 +83,8 @@ Reduction JSNativeContextSpecialization::Reduce(Node* node) {
return ReduceJSLoadProperty(node);
case IrOpcode::kJSStoreProperty:
return ReduceJSStoreProperty(node);
case IrOpcode::kJSStoreDataPropertyInLiteral:
return ReduceJSStoreDataPropertyInLiteral(node);
default:
break;
}
......@@ -1252,6 +1254,12 @@ JSNativeContextSpecialization::BuildPropertyAccess(
return ValueEffectControl(value, effect, control);
}
Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
Node* node) {
// TODO(franzih): Use feedback
return NoChange();
}
namespace {
ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
......
......@@ -60,6 +60,7 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
Reduction ReduceJSStoreNamed(Node* node);
Reduction ReduceJSLoadProperty(Node* node);
Reduction ReduceJSStoreProperty(Node* node);
Reduction ReduceJSStoreDataPropertyInLiteral(Node* node);
Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
MapHandleList const& receiver_maps,
......
......@@ -246,6 +246,29 @@ CreateFunctionContextParameters const& CreateFunctionContextParametersOf(
return OpParameter<CreateFunctionContextParameters>(op);
}
bool operator==(DataPropertyParameters const& lhs,
DataPropertyParameters const& rhs) {
return lhs.feedback() == rhs.feedback();
}
bool operator!=(DataPropertyParameters const& lhs,
DataPropertyParameters const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(DataPropertyParameters const& p) {
return base::hash_combine(p.feedback());
}
std::ostream& operator<<(std::ostream& os, DataPropertyParameters const& p) {
return os;
}
DataPropertyParameters const& DataPropertyParametersOf(const Operator* op) {
DCHECK(op->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral);
return OpParameter<DataPropertyParameters>(op);
}
bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) {
return lhs.name().location() == rhs.name().location() &&
lhs.language_mode() == rhs.language_mode() &&
......@@ -511,8 +534,7 @@ CompareOperationHint CompareOperationHintOf(const Operator* op) {
V(StoreMessage, Operator::kNoThrow, 1, 0) \
V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \
V(StackCheck, Operator::kNoWrite, 0, 0) \
V(GetSuperConstructor, Operator::kNoWrite, 1, 1) \
V(StoreDataPropertyInLiteral, Operator::kNoProperties, 4, 0)
V(GetSuperConstructor, Operator::kNoWrite, 1, 1)
#define BINARY_OP_LIST(V) \
V(BitwiseOr) \
......@@ -651,6 +673,17 @@ BINARY_OP_LIST(BINARY_OP)
COMPARE_OP_LIST(COMPARE_OP)
#undef COMPARE_OP
const Operator* JSOperatorBuilder::StoreDataPropertyInLiteral(
const VectorSlotPair& feedback) {
DataPropertyParameters parameters(feedback);
return new (zone()) Operator1<DataPropertyParameters>( // --
IrOpcode::kJSStoreDataPropertyInLiteral,
Operator::kNoThrow, // opcode
"JSStoreDataPropertyInLiteral", // name
4, 1, 1, 0, 1, 0, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::ToBoolean(ToBooleanHints hints) {
// TODO(turbofan): Cache most important versions of this operator.
return new (zone()) Operator1<ToBooleanHints>( //--
......
......@@ -268,6 +268,29 @@ std::ostream& operator<<(std::ostream& os,
CreateFunctionContextParameters const& CreateFunctionContextParametersOf(
Operator const*);
// 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.
class DataPropertyParameters final {
public:
explicit DataPropertyParameters(VectorSlotPair const& feedback)
: feedback_(feedback) {}
VectorSlotPair const& feedback() const { return feedback_; }
private:
VectorSlotPair const feedback_;
};
bool operator==(DataPropertyParameters const&, DataPropertyParameters const&);
bool operator!=(DataPropertyParameters const&, DataPropertyParameters const&);
size_t hash_value(DataPropertyParameters const&);
std::ostream& operator<<(std::ostream&, DataPropertyParameters const&);
const DataPropertyParameters& DataPropertyParametersOf(const Operator* op);
// Defines the property of an object for a named access. This is
// used as a parameter by the JSLoadNamed and JSStoreNamed operators.
class NamedAccess final {
......@@ -542,7 +565,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* StoreNamed(LanguageMode language_mode, Handle<Name> name,
VectorSlotPair const& feedback);
const Operator* StoreDataPropertyInLiteral();
const Operator* StoreDataPropertyInLiteral(const VectorSlotPair& feedback);
const Operator* DeleteProperty(LanguageMode language_mode);
......
......@@ -554,9 +554,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreDataPropertyInLiteral(
Register object, Register name, Register value,
DataPropertyInLiteralFlags flags) {
OutputStaDataPropertyInLiteral(object, name, value, flags);
Register object, Register name, DataPropertyInLiteralFlags flags,
int feedback_slot) {
OutputStaDataPropertyInLiteral(object, name, flags, feedback_slot);
return *this;
}
......
......@@ -125,8 +125,8 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
// Store properties. Flag for NeedsSetFunctionName() should
// be in the accumulator.
BytecodeArrayBuilder& StoreDataPropertyInLiteral(
Register object, Register name, Register value,
DataPropertyInLiteralFlags flags);
Register object, Register name, DataPropertyInLiteralFlags flags,
int feedback_slot);
// Store properties. The value to be stored should be in the accumulator.
BytecodeArrayBuilder& StoreNamedProperty(Register object,
......
......@@ -1503,7 +1503,14 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
if (property->NeedsSetFunctionName()) {
flags |= DataPropertyInLiteralFlag::kSetFunctionName;
}
builder()->StoreDataPropertyInLiteral(receiver, key, value, flags);
FeedbackVectorSlot slot = property->GetStoreDataPropertySlot();
DCHECK(!slot.IsInvalid());
builder()
->LoadAccumulatorWithRegister(value)
.StoreDataPropertyInLiteral(receiver, key, flags,
feedback_index(slot));
break;
}
case ClassLiteral::Property::GETTER: {
......@@ -1745,8 +1752,13 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
data_property_flags |= DataPropertyInLiteralFlag::kSetFunctionName;
}
builder()->StoreDataPropertyInLiteral(literal, key, value,
data_property_flags);
FeedbackVectorSlot slot = property->GetStoreDataPropertySlot();
DCHECK(!slot.IsInvalid());
builder()
->LoadAccumulatorWithRegister(value)
.StoreDataPropertyInLiteral(literal, key, data_property_flags,
feedback_index(slot));
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::kNone, OperandType::kReg, \
OperandType::kReg, OperandType::kReg, OperandType::kFlag8) \
V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kReg, OperandType::kFlag8, OperandType::kIdx) \
\
/* Binary Operators */ \
V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \
......
......@@ -861,27 +861,26 @@ void Interpreter::DoStaKeyedPropertyStrict(InterpreterAssembler* assembler) {
DoKeyedStoreIC(ic, assembler);
}
// StaDataPropertyInLiteral <object> <name> <value> <flags>
// StaDataPropertyInLiteral <object> <name> <flags>
//
// Define a property <name> with value <value> in <object>. Property attributes
// and whether set_function_name are stored in DataPropertyInLiteralFlags
// <flags>.
// Define a property <name> with value from the accumulator 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.
void Interpreter::DoStaDataPropertyInLiteral(InterpreterAssembler* assembler) {
Node* object_reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(object_reg_index);
Node* name_reg_index = __ BytecodeOperandReg(1);
Node* name = __ LoadRegister(name_reg_index);
Node* value_reg_index = __ BytecodeOperandReg(2);
Node* value = __ LoadRegister(value_reg_index);
Node* flags = __ SmiFromWord32(__ BytecodeOperandFlag(3));
Node* object = __ LoadRegister(__ BytecodeOperandReg(0));
Node* name = __ LoadRegister(__ BytecodeOperandReg(1));
Node* value = __ GetAccumulator();
Node* flags = __ SmiFromWord32(__ BytecodeOperandFlag(2));
Node* vector_index = __ SmiTag(__ BytecodeOperandIdx(3));
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* context = __ GetContext();
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral, context, object, name,
value, flags);
value, flags, type_feedback_vector, vector_index);
__ Dispatch();
}
......
......@@ -799,6 +799,11 @@ void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) { // NOLINT
os << Code::ICState2String(nexus.StateFromFeedback());
break;
}
case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC: {
StoreDataPropertyInLiteralICNexus nexus(this, slot);
os << Code::ICState2String(nexus.StateFromFeedback());
break;
}
case FeedbackVectorSlotKind::GENERAL:
break;
case FeedbackVectorSlotKind::INVALID:
......
......@@ -648,11 +648,27 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
DCHECK_EQ(6, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_SMI_ARG_CHECKED(flag, 3);
CONVERT_ARG_HANDLE_CHECKED(TypeFeedbackVector, vector, 4);
CONVERT_SMI_ARG_CHECKED(index, 5);
StoreDataPropertyInLiteralICNexus nexus(vector, vector->ToSlot(index));
if (nexus.ic_state() == UNINITIALIZED) {
if (name->IsUniqueName()) {
nexus.ConfigureMonomorphic(name, handle(object->map()));
} else {
nexus.ConfigureMegamorphic();
}
} else if (nexus.ic_state() == MONOMORPHIC) {
if (nexus.FindFirstMap() != object->map() ||
nexus.GetFeedbackExtra() != *name) {
nexus.ConfigureMegamorphic();
}
}
DataPropertyInLiteralFlags flags =
static_cast<DataPropertyInLiteralFlag>(flag);
......
......@@ -409,7 +409,7 @@ namespace internal {
F(TryMigrateInstance, 1, 1) \
F(IsJSGlobalProxy, 1, 1) \
F(DefineAccessorPropertyUnchecked, 5, 1) \
F(DefineDataPropertyInLiteral, 4, 1) \
F(DefineDataPropertyInLiteral, 6, 1) \
F(GetDataProperty, 2, 1) \
F(GetConstructorName, 1, 1) \
F(HasFastPackedElements, 1, 1) \
......
......@@ -82,7 +82,7 @@ int TypeFeedbackVector::invocation_count() const {
// Conversion from an integer index to either a slot or an ic slot.
// static
FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) {
DCHECK(index >= kReservedIndexCount);
DCHECK_GE(index, kReservedIndexCount);
return FeedbackVectorSlot(index - kReservedIndexCount);
}
......@@ -159,7 +159,8 @@ void TypeFeedbackVector::ComputeCounts(int* with_type_info, int* generic,
case FeedbackVectorSlotKind::LOAD_GLOBAL_IC:
case FeedbackVectorSlotKind::KEYED_LOAD_IC:
case FeedbackVectorSlotKind::STORE_IC:
case FeedbackVectorSlotKind::KEYED_STORE_IC: {
case FeedbackVectorSlotKind::KEYED_STORE_IC:
case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC: {
if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
with++;
} else if (obj == megamorphic_sentinel) {
......
......@@ -161,6 +161,8 @@ const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) {
return "INTERPRETER_BINARYOP_IC";
case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC:
return "INTERPRETER_COMPARE_IC";
case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC:
return "STORE_DATA_PROPERTY_IN_LITERAL_IC";
case FeedbackVectorSlotKind::GENERAL:
return "STUB";
case FeedbackVectorSlotKind::KINDS_NUMBER:
......@@ -316,6 +318,11 @@ void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
}
break;
}
case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC: {
StoreDataPropertyInLiteralICNexus nexus(this, slot);
nexus.Clear(shared->code());
break;
}
case FeedbackVectorSlotKind::INVALID:
case FeedbackVectorSlotKind::KINDS_NUMBER:
UNREACHABLE();
......@@ -987,5 +994,27 @@ CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const {
return CompareOperationHintFromFeedback(feedback);
}
InlineCacheState StoreDataPropertyInLiteralICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) {
return UNINITIALIZED;
} else if (feedback->IsWeakCell()) {
// Don't check if the map is cleared.
return MONOMORPHIC;
}
return MEGAMORPHIC;
}
void StoreDataPropertyInLiteralICNexus::ConfigureMonomorphic(
Handle<Name> name, Handle<Map> receiver_map) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
SetFeedback(*cell);
SetFeedbackExtra(*name);
}
} // namespace internal
} // namespace v8
......@@ -30,6 +30,7 @@ enum class FeedbackVectorSlotKind {
KEYED_STORE_IC,
INTERPRETER_BINARYOP_IC,
INTERPRETER_COMPARE_IC,
STORE_DATA_PROPERTY_IN_LITERAL_IC,
// This is a general purpose slot that occupies one feedback vector element.
GENERAL,
......@@ -81,6 +82,10 @@ class FeedbackVectorSpecBase {
return AddSlot(FeedbackVectorSlotKind::GENERAL);
}
FeedbackVectorSlot AddStoreDataPropertyInLiteralICSlot() {
return AddSlot(FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC);
}
#ifdef OBJECT_PRINT
// For gdb debugging.
void Print();
......@@ -667,6 +672,28 @@ class CompareICNexus final : public FeedbackNexus {
}
};
class StoreDataPropertyInLiteralICNexus : public FeedbackNexus {
public:
StoreDataPropertyInLiteralICNexus(Handle<TypeFeedbackVector> vector,
FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC,
vector->GetKind(slot));
}
StoreDataPropertyInLiteralICNexus(TypeFeedbackVector* vector,
FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC,
vector->GetKind(slot));
}
void Clear(Code* host) { ConfigureUninitialized(); }
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map);
InlineCacheState StateFromFeedback() const override;
};
inline BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback);
inline CompareOperationHint CompareOperationHintFromFeedback(int type_feedback);
......
......@@ -12,9 +12,9 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 8
frame size: 9
parameter count: 1
bytecode array length: 69
bytecode array length: 73
bytecodes: [
B(LdaTheHole),
B(Star), R(2),
......@@ -37,7 +37,9 @@ bytecodes: [
B(CreateClosure), U8(2), U8(2),
B(Star), R(7),
B(LdaSmi), U8(2),
B(StaDataPropertyInLiteral), R(4), R(6), R(7), U8(1),
B(Star), R(8),
B(Ldar), R(7),
B(StaDataPropertyInLiteral), R(4), R(6), U8(1), U8(2),
B(CallRuntime), U16(Runtime::kInstallClassNameAccessor), R(3), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(Star), R(0),
......@@ -61,9 +63,9 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 8
frame size: 9
parameter count: 1
bytecode array length: 69
bytecode array length: 73
bytecodes: [
B(LdaTheHole),
B(Star), R(2),
......@@ -86,7 +88,9 @@ bytecodes: [
B(CreateClosure), U8(2), U8(2),
B(Star), R(7),
B(LdaSmi), U8(2),
B(StaDataPropertyInLiteral), R(4), R(6), R(7), U8(1),
B(Star), R(8),
B(Ldar), R(7),
B(StaDataPropertyInLiteral), R(4), R(6), U8(1), U8(2),
B(CallRuntime), U16(Runtime::kInstallClassNameAccessor), R(3), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(Star), R(0),
......@@ -114,7 +118,7 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 112
bytecode array length: 114
bytecodes: [
B(CreateFunctionContext), U8(2),
B(PushContext), R(3),
......@@ -143,8 +147,9 @@ bytecodes: [
B(CreateClosure), U8(3), 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(Ldar), R(8),
B(StaDataPropertyInLiteral), R(5), R(7), U8(3), U8(2),
B(LdaCurrentContextSlot), U8(5),
/* 106 E> */ B(ToName), R(7),
B(LdaConstant), U8(4),
......@@ -154,7 +159,7 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(CreateClosure), U8(5), U8(2),
B(Star), R(8),
B(StaDataPropertyInLiteral), R(6), R(7), R(8), U8(3),
B(StaDataPropertyInLiteral), R(6), R(7), U8(3), U8(4),
B(CallRuntime), U16(Runtime::kInstallClassNameAccessorWithCheck), R(4), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
B(Star), R(0),
......@@ -224,9 +229,9 @@ snippet: "
(class {})
class E { static name () {}}
"
frame size: 9
frame size: 10
parameter count: 1
bytecode array length: 95
bytecode array length: 99
bytecodes: [
B(LdaTheHole),
B(Star), R(3),
......@@ -262,7 +267,9 @@ bytecodes: [
B(CreateClosure), U8(3), U8(2),
B(Star), R(8),
B(LdaSmi), U8(2),
B(StaDataPropertyInLiteral), R(6), R(7), R(8), U8(1),
B(Star), R(9),
B(Ldar), R(8),
B(StaDataPropertyInLiteral), R(6), R(7), U8(1), U8(2),
B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
B(Star), R(0),
B(Star), R(2),
......
......@@ -296,7 +296,7 @@ bytecodes: [
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), U8(0),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(2),
B(Ldar), R(1),
/* 69 S> */ B(Return),
]
......@@ -323,7 +323,7 @@ bytecodes: [
/* 68 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), U8(0),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(4),
B(Ldar), R(1),
/* 77 S> */ B(Return),
]
......@@ -350,7 +350,7 @@ bytecodes: [
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), U8(0),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(2),
B(CreateObjectLiteral), U8(1), U8(0), U8(35), R(4),
B(Mov), R(1), R(2),
B(Mov), R(4), R(3),
......@@ -380,7 +380,7 @@ bytecodes: [
/* 60 E> */ B(ToName), R(2),
B(LdaConstant), U8(2),
B(Star), R(3),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), U8(0),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(2),
B(LdaConstant), U8(3),
B(ToName), R(3),
B(CreateClosure), U8(4), U8(2),
......
......@@ -324,8 +324,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreNamedProperty(reg, wide_name, 0, LanguageMode::STRICT)
.StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
builder.StoreDataPropertyInLiteral(reg, reg, reg,
DataPropertyInLiteralFlag::kNoFlags);
builder.StoreDataPropertyInLiteral(reg, reg,
DataPropertyInLiteralFlag::kNoFlags, 0);
// 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