| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index a92aca9ade80aaa8c9bd159b1731311e09e7d1d2..6f4dc275c1f636222258f228bf6d0dc423385a3f 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -417,11 +417,6 @@ class BytecodeGenerator::RegisterAllocationScope {
|
| return allocator_.NextConsecutiveRegister();
|
| }
|
|
|
| - template <size_t N>
|
| - void PrepareAndInitializeConsecutiveAllocations(Register (®isters)[N]) {
|
| - return allocator_.PrepareAndInitializeConsecutiveAllocations(registers, N);
|
| - }
|
| -
|
| bool RegisterIsAllocatedInThisScope(Register reg) const {
|
| return allocator_.RegisterIsAllocatedInThisScope(reg);
|
| }
|
| @@ -547,26 +542,6 @@ class BytecodeGenerator::RegisterResultScope final
|
| Register result_register_;
|
| };
|
|
|
| -// Class for holding arguments for runtime calls relating to super
|
| -// properties.
|
| -class BytecodeGenerator::SuperPropertyArguments final {
|
| - public:
|
| - SuperPropertyArguments() {}
|
| -
|
| - Register (®isters())[4] { return args_; }
|
| - Register receiver() const { return args_[0]; }
|
| - Register home_object() const { return args_[1]; }
|
| - Register name_or_key() const { return args_[2]; }
|
| - Register store_value() const { return args_[3]; }
|
| - Register language_mode() const { return args_[3]; }
|
| - size_t count() const { return arraysize(args_); }
|
| -
|
| - private:
|
| - Register args_[4];
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SuperPropertyArguments);
|
| -};
|
| -
|
| BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
|
| : isolate_(isolate),
|
| zone_(zone),
|
| @@ -1074,26 +1049,36 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr,
|
| }
|
| case NAMED_SUPER_PROPERTY: {
|
| RegisterAllocationScope register_scope(this);
|
| - SuperPropertyArguments super_args;
|
| - Register value = register_allocator()->NewRegister();
|
| + register_allocator()->PrepareForConsecutiveAllocations(4);
|
| + Register receiver = register_allocator()->NextConsecutiveRegister();
|
| + Register home_object = register_allocator()->NextConsecutiveRegister();
|
| + Register name = register_allocator()->NextConsecutiveRegister();
|
| + Register value = register_allocator()->NextConsecutiveRegister();
|
| builder()->StoreAccumulatorInRegister(value);
|
| - PrepareNamedSuperPropertyArguments(
|
| - property->obj()->AsSuperPropertyReference(),
|
| - property->key()->AsLiteral()->AsPropertyName(), &super_args);
|
| - builder()->LoadAccumulatorWithRegister(value);
|
| - BuildNamedSuperPropertyStore(&super_args);
|
| + SuperPropertyReference* super_property =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForRegisterValue(super_property->this_var(), receiver);
|
| + VisitForRegisterValue(super_property->home_object(), home_object);
|
| + builder()
|
| + ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
|
| + .StoreAccumulatorInRegister(name);
|
| + BuildNamedSuperPropertyStore(receiver, home_object, name, value);
|
| break;
|
| }
|
| case KEYED_SUPER_PROPERTY: {
|
| RegisterAllocationScope register_scope(this);
|
| - SuperPropertyArguments super_args;
|
| - Register value = register_allocator()->NewRegister();
|
| + register_allocator()->PrepareForConsecutiveAllocations(4);
|
| + Register receiver = register_allocator()->NextConsecutiveRegister();
|
| + Register home_object = register_allocator()->NextConsecutiveRegister();
|
| + Register key = register_allocator()->NextConsecutiveRegister();
|
| + Register value = register_allocator()->NextConsecutiveRegister();
|
| builder()->StoreAccumulatorInRegister(value);
|
| - PrepareKeyedSuperPropertyArguments(
|
| - property->obj()->AsSuperPropertyReference(), property->key(),
|
| - &super_args);
|
| - builder()->LoadAccumulatorWithRegister(value);
|
| - BuildKeyedSuperPropertyStore(&super_args);
|
| + SuperPropertyReference* super_property =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForRegisterValue(super_property->this_var(), receiver);
|
| + VisitForRegisterValue(super_property->home_object(), home_object);
|
| + VisitForRegisterValue(property->key(), key);
|
| + BuildKeyedSuperPropertyStore(receiver, home_object, key, value);
|
| break;
|
| }
|
| }
|
| @@ -1834,65 +1819,40 @@ Register BytecodeGenerator::VisitVariableLoadForRegisterValue(
|
| return register_scope.ResultRegister();
|
| }
|
|
|
| -void BytecodeGenerator::PrepareNamedSuperPropertyArguments(
|
| - SuperPropertyReference* super_property, Handle<Name> name,
|
| - SuperPropertyArguments* super_args) {
|
| - register_allocator()->PrepareAndInitializeConsecutiveAllocations(
|
| - super_args->registers());
|
| -
|
| - VisitForAccumulatorValue(super_property->this_var());
|
| - builder()->StoreAccumulatorInRegister(super_args->receiver());
|
| - VisitForAccumulatorValue(super_property->home_object());
|
| - builder()->StoreAccumulatorInRegister(super_args->home_object());
|
| - builder()->LoadLiteral(name).StoreAccumulatorInRegister(
|
| - super_args->name_or_key());
|
| -}
|
| -
|
| -void BytecodeGenerator::PrepareKeyedSuperPropertyArguments(
|
| - SuperPropertyReference* super_property, Expression* key,
|
| - SuperPropertyArguments* super_args) {
|
| - register_allocator()->PrepareAndInitializeConsecutiveAllocations(
|
| - super_args->registers());
|
| -
|
| - VisitForAccumulatorValue(super_property->this_var());
|
| - builder()->StoreAccumulatorInRegister(super_args->receiver());
|
| - VisitForAccumulatorValue(super_property->home_object());
|
| - builder()->StoreAccumulatorInRegister(super_args->home_object());
|
| - VisitForAccumulatorValue(key);
|
| - builder()->StoreAccumulatorInRegister(super_args->name_or_key());
|
| +void BytecodeGenerator::BuildNamedSuperPropertyLoad(Register receiver,
|
| + Register home_object,
|
| + Register name) {
|
| + DCHECK(Register::AreContiguous(receiver, home_object, name));
|
| + builder()->CallRuntime(Runtime::kLoadFromSuper, receiver, 3);
|
| }
|
|
|
| -void BytecodeGenerator::BuildNamedSuperPropertyLoad(
|
| - SuperPropertyArguments* super_args) {
|
| - // TODO(oth): Abstraction not suitable for 3 args, will over-allocate regs.
|
| - builder()->CallRuntime(Runtime::kLoadFromSuper, super_args->receiver(), 3);
|
| +void BytecodeGenerator::BuildKeyedSuperPropertyLoad(Register receiver,
|
| + Register home_object,
|
| + Register key) {
|
| + DCHECK(Register::AreContiguous(receiver, home_object, key));
|
| + builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, receiver, 3);
|
| }
|
|
|
| -void BytecodeGenerator::BuildKeyedSuperPropertyLoad(
|
| - SuperPropertyArguments* super_args) {
|
| - // TODO(oth): Abstraction not suitable for 3 args, will over-allocate regs.
|
| - builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, super_args->receiver(),
|
| - 3);
|
| -}
|
| -
|
| -void BytecodeGenerator::BuildNamedSuperPropertyStore(
|
| - SuperPropertyArguments* super_args) {
|
| - builder()->StoreAccumulatorInRegister(super_args->store_value());
|
| +void BytecodeGenerator::BuildNamedSuperPropertyStore(Register receiver,
|
| + Register home_object,
|
| + Register name,
|
| + Register value) {
|
| + DCHECK(Register::AreContiguous(receiver, home_object, name, value));
|
| Runtime::FunctionId function_id = is_strict(language_mode())
|
| ? Runtime::kStoreToSuper_Strict
|
| : Runtime::kStoreToSuper_Sloppy;
|
| - builder()->CallRuntime(function_id, super_args->receiver(),
|
| - super_args->count());
|
| + builder()->CallRuntime(function_id, receiver, 4);
|
| }
|
|
|
| -void BytecodeGenerator::BuildKeyedSuperPropertyStore(
|
| - SuperPropertyArguments* super_args) {
|
| - builder()->StoreAccumulatorInRegister(super_args->store_value());
|
| +void BytecodeGenerator::BuildKeyedSuperPropertyStore(Register receiver,
|
| + Register home_object,
|
| + Register key,
|
| + Register value) {
|
| + DCHECK(Register::AreContiguous(receiver, home_object, key, value));
|
| Runtime::FunctionId function_id = is_strict(language_mode())
|
| ? Runtime::kStoreKeyedToSuper_Strict
|
| : Runtime::kStoreKeyedToSuper_Sloppy;
|
| - builder()->CallRuntime(function_id, super_args->receiver(),
|
| - super_args->count());
|
| + builder()->CallRuntime(function_id, receiver, 4);
|
| }
|
|
|
| void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) {
|
| @@ -2103,8 +2063,7 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
|
|
| void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
| DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
|
| - Register object, key;
|
| - SuperPropertyArguments super_args;
|
| + Register object, key, home_object, value;
|
| Handle<String> name;
|
|
|
| // Left-hand side can only be a property, a global or a variable slot.
|
| @@ -2135,15 +2094,32 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
| break;
|
| }
|
| case NAMED_SUPER_PROPERTY: {
|
| - PrepareNamedSuperPropertyArguments(
|
| - property->obj()->AsSuperPropertyReference(),
|
| - property->key()->AsLiteral()->AsPropertyName(), &super_args);
|
| + register_allocator()->PrepareForConsecutiveAllocations(4);
|
| + object = register_allocator()->NextConsecutiveRegister();
|
| + home_object = register_allocator()->NextConsecutiveRegister();
|
| + key = register_allocator()->NextConsecutiveRegister();
|
| + value = register_allocator()->NextConsecutiveRegister();
|
| + SuperPropertyReference* super_property =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForRegisterValue(super_property->this_var(), object);
|
| + VisitForRegisterValue(super_property->home_object(), home_object);
|
| + builder()
|
| + ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
|
| + .StoreAccumulatorInRegister(key);
|
| break;
|
| }
|
| case KEYED_SUPER_PROPERTY: {
|
| - PrepareKeyedSuperPropertyArguments(
|
| - property->obj()->AsSuperPropertyReference(), property->key(),
|
| - &super_args);
|
| + register_allocator()->PrepareForConsecutiveAllocations(4);
|
| + object = register_allocator()->NextConsecutiveRegister();
|
| + home_object = register_allocator()->NextConsecutiveRegister();
|
| + key = register_allocator()->NextConsecutiveRegister();
|
| + value = register_allocator()->NextConsecutiveRegister();
|
| + builder()->StoreAccumulatorInRegister(value);
|
| + SuperPropertyReference* super_property =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForRegisterValue(super_property->this_var(), object);
|
| + VisitForRegisterValue(super_property->home_object(), home_object);
|
| + VisitForRegisterValue(property->key(), key);
|
| break;
|
| }
|
| }
|
| @@ -2179,13 +2155,13 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
| }
|
| case NAMED_SUPER_PROPERTY: {
|
| old_value = register_allocator()->NewRegister();
|
| - BuildNamedSuperPropertyLoad(&super_args);
|
| + BuildNamedSuperPropertyLoad(object, home_object, key);
|
| builder()->StoreAccumulatorInRegister(old_value);
|
| break;
|
| }
|
| case KEYED_SUPER_PROPERTY: {
|
| old_value = register_allocator()->NewRegister();
|
| - BuildKeyedSuperPropertyLoad(&super_args);
|
| + BuildKeyedSuperPropertyLoad(object, home_object, key);
|
| builder()->StoreAccumulatorInRegister(old_value);
|
| break;
|
| }
|
| @@ -2215,11 +2191,13 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
| language_mode());
|
| break;
|
| case NAMED_SUPER_PROPERTY: {
|
| - BuildNamedSuperPropertyStore(&super_args);
|
| + builder()->StoreAccumulatorInRegister(value);
|
| + BuildNamedSuperPropertyStore(object, home_object, key, value);
|
| break;
|
| }
|
| case KEYED_SUPER_PROPERTY: {
|
| - BuildKeyedSuperPropertyStore(&super_args);
|
| + builder()->StoreAccumulatorInRegister(value);
|
| + BuildKeyedSuperPropertyStore(object, home_object, key, value);
|
| break;
|
| }
|
| }
|
| @@ -2277,27 +2255,45 @@ void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj,
|
| void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property,
|
| Register opt_receiver_out) {
|
| RegisterAllocationScope register_scope(this);
|
| - SuperPropertyArguments super_args;
|
| - PrepareNamedSuperPropertyArguments(
|
| - property->obj()->AsSuperPropertyReference(),
|
| - property->key()->AsLiteral()->AsPropertyName(), &super_args);
|
| + register_allocator()->PrepareForConsecutiveAllocations(3);
|
| +
|
| + Register receiver, home_object, name;
|
| + receiver = register_allocator()->NextConsecutiveRegister();
|
| + home_object = register_allocator()->NextConsecutiveRegister();
|
| + name = register_allocator()->NextConsecutiveRegister();
|
| + SuperPropertyReference* super_property =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForRegisterValue(super_property->this_var(), receiver);
|
| + VisitForRegisterValue(super_property->home_object(), home_object);
|
| + builder()
|
| + ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
|
| + .StoreAccumulatorInRegister(name);
|
| + BuildNamedSuperPropertyLoad(receiver, home_object, name);
|
| +
|
| if (opt_receiver_out.is_valid()) {
|
| - builder()->MoveRegister(super_args.receiver(), opt_receiver_out);
|
| + builder()->MoveRegister(receiver, opt_receiver_out);
|
| }
|
| - BuildNamedSuperPropertyLoad(&super_args);
|
| }
|
|
|
| void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
|
| Register opt_receiver_out) {
|
| RegisterAllocationScope register_scope(this);
|
| - SuperPropertyArguments super_args;
|
| - PrepareKeyedSuperPropertyArguments(
|
| - property->obj()->AsSuperPropertyReference(), property->key(),
|
| - &super_args);
|
| + register_allocator()->PrepareForConsecutiveAllocations(3);
|
| +
|
| + Register receiver, home_object, key;
|
| + receiver = register_allocator()->NextConsecutiveRegister();
|
| + home_object = register_allocator()->NextConsecutiveRegister();
|
| + key = register_allocator()->NextConsecutiveRegister();
|
| + SuperPropertyReference* super_property =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForRegisterValue(super_property->this_var(), receiver);
|
| + VisitForRegisterValue(super_property->home_object(), home_object);
|
| + VisitForRegisterValue(property->key(), key);
|
| + BuildKeyedSuperPropertyLoad(receiver, home_object, key);
|
| +
|
| if (opt_receiver_out.is_valid()) {
|
| - builder()->MoveRegister(super_args.receiver(), opt_receiver_out);
|
| + builder()->MoveRegister(receiver, opt_receiver_out);
|
| }
|
| - BuildKeyedSuperPropertyLoad(&super_args);
|
| }
|
|
|
| void BytecodeGenerator::VisitProperty(Property* expr) {
|
| @@ -2661,8 +2657,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| bool is_postfix = expr->is_postfix();
|
|
|
| // Evaluate LHS expression and get old value.
|
| - Register object, key, old_value;
|
| - SuperPropertyArguments super_args;
|
| + Register object, home_object, key, old_value, value;
|
| Handle<String> name;
|
| switch (assign_type) {
|
| case VARIABLE: {
|
| @@ -2690,17 +2685,34 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| break;
|
| }
|
| case NAMED_SUPER_PROPERTY: {
|
| - PrepareNamedSuperPropertyArguments(
|
| - property->obj()->AsSuperPropertyReference(),
|
| - property->key()->AsLiteral()->AsPropertyName(), &super_args);
|
| - BuildNamedSuperPropertyLoad(&super_args);
|
| + register_allocator()->PrepareForConsecutiveAllocations(4);
|
| + object = register_allocator()->NextConsecutiveRegister();
|
| + home_object = register_allocator()->NextConsecutiveRegister();
|
| + key = register_allocator()->NextConsecutiveRegister();
|
| + value = register_allocator()->NextConsecutiveRegister();
|
| + SuperPropertyReference* super_property =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForRegisterValue(super_property->this_var(), object);
|
| + VisitForRegisterValue(super_property->home_object(), home_object);
|
| + builder()
|
| + ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
|
| + .StoreAccumulatorInRegister(key);
|
| + BuildNamedSuperPropertyLoad(object, home_object, key);
|
| break;
|
| }
|
| case KEYED_SUPER_PROPERTY: {
|
| - PrepareKeyedSuperPropertyArguments(
|
| - property->obj()->AsSuperPropertyReference(), property->key(),
|
| - &super_args);
|
| - BuildKeyedSuperPropertyLoad(&super_args);
|
| + register_allocator()->PrepareForConsecutiveAllocations(4);
|
| + object = register_allocator()->NextConsecutiveRegister();
|
| + home_object = register_allocator()->NextConsecutiveRegister();
|
| + key = register_allocator()->NextConsecutiveRegister();
|
| + value = register_allocator()->NextConsecutiveRegister();
|
| + builder()->StoreAccumulatorInRegister(value);
|
| + SuperPropertyReference* super_property =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForRegisterValue(super_property->this_var(), object);
|
| + VisitForRegisterValue(super_property->home_object(), home_object);
|
| + VisitForRegisterValue(property->key(), key);
|
| + BuildKeyedSuperPropertyLoad(object, home_object, key);
|
| break;
|
| }
|
| }
|
| @@ -2738,11 +2750,13 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| break;
|
| }
|
| case NAMED_SUPER_PROPERTY: {
|
| - BuildNamedSuperPropertyStore(&super_args);
|
| + builder()->StoreAccumulatorInRegister(value);
|
| + BuildNamedSuperPropertyStore(object, home_object, key, value);
|
| break;
|
| }
|
| case KEYED_SUPER_PROPERTY: {
|
| - BuildKeyedSuperPropertyStore(&super_args);
|
| + builder()->StoreAccumulatorInRegister(value);
|
| + BuildKeyedSuperPropertyStore(object, home_object, key, value);
|
| break;
|
| }
|
| }
|
| @@ -3098,6 +3112,14 @@ Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) {
|
| return register_scope.ResultRegister();
|
| }
|
|
|
| +// Visits the expression |expr| and stores the expression result in
|
| +// |destination|.
|
| +void BytecodeGenerator::VisitForRegisterValue(Expression* expr,
|
| + Register destination) {
|
| + AccumulatorResultScope register_scope(this);
|
| + Visit(expr);
|
| + builder()->StoreAccumulatorInRegister(destination);
|
| +}
|
|
|
| void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) {
|
| ContextScope context_scope(this, scope);
|
|
|