[interpreter] Clean super property handling.

SuperPropertyArgumnets is less useful after deprecating strong mode.

BUG=v8:4280,v8:4682
LOG=N

Review URL: https://codereview.chromium.org/1721723002

Cr-Commit-Position: refs/heads/master@{#34215}
This commit is contained in:
oth 2016-02-23 07:40:58 -08:00 committed by Commit bot
parent 113d303534
commit bd9df50d75
4 changed files with 153 additions and 148 deletions

View File

@ -417,11 +417,6 @@ class BytecodeGenerator::RegisterAllocationScope {
return allocator_.NextConsecutiveRegister();
}
template <size_t N>
void PrepareAndInitializeConsecutiveAllocations(Register (&registers)[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 (&registers())[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::BuildNamedSuperPropertyLoad(Register receiver,
Register home_object,
Register name) {
DCHECK(Register::AreContiguous(receiver, home_object, name));
builder()->CallRuntime(Runtime::kLoadFromSuper, receiver, 3);
}
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::BuildKeyedSuperPropertyLoad(Register receiver,
Register home_object,
Register key) {
DCHECK(Register::AreContiguous(receiver, home_object, key));
builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, 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(
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);

View File

@ -42,7 +42,6 @@ class BytecodeGenerator final : public AstVisitor {
class AccumulatorResultScope;
class RegisterResultScope;
class RegisterAllocationScope;
class SuperPropertyArguments;
void MakeBytecodeBody();
@ -94,18 +93,14 @@ class BytecodeGenerator final : public AstVisitor {
void VisitVariableAssignment(Variable* variable, Token::Value op,
FeedbackVectorSlot slot);
void PrepareNamedSuperPropertyArguments(
SuperPropertyReference* super_property, Handle<Name> name,
SuperPropertyArguments* super_property_args);
void PrepareKeyedSuperPropertyArguments(
SuperPropertyReference* super_property, Expression* key,
SuperPropertyArguments* super_property_args);
void BuildNamedSuperPropertyLoad(SuperPropertyArguments* super_property_args);
void BuildKeyedSuperPropertyLoad(SuperPropertyArguments* super_property_args);
void BuildNamedSuperPropertyStore(
SuperPropertyArguments* super_property_args);
void BuildKeyedSuperPropertyStore(
SuperPropertyArguments* super_property_args);
void BuildNamedSuperPropertyStore(Register receiver, Register home_object,
Register name, Register value);
void BuildKeyedSuperPropertyStore(Register receiver, Register home_object,
Register key, Register value);
void BuildNamedSuperPropertyLoad(Register receiver, Register home_object,
Register name);
void BuildKeyedSuperPropertyLoad(Register receiver, Register home_object,
Register key);
void BuildThrowIfHole(Handle<String> name);
void BuildThrowIfNotHole(Handle<String> name);
@ -149,6 +144,7 @@ class BytecodeGenerator final : public AstVisitor {
void VisitForAccumulatorValue(Expression* expr);
void VisitForAccumulatorValueOrTheHole(Expression* expr);
MUST_USE_RESULT Register VisitForRegisterValue(Expression* expr);
void VisitForRegisterValue(Expression* expr, Register destination);
void VisitForEffect(Expression* expr);
// Methods for tracking and remapping register.

View File

@ -224,14 +224,6 @@ Register BytecodeRegisterAllocator::NextConsecutiveRegister() {
return Register(next_consecutive_register_++);
}
void BytecodeRegisterAllocator::PrepareAndInitializeConsecutiveAllocations(
Register* registers, size_t count) {
PrepareForConsecutiveAllocations(count);
for (size_t i = 0; i < count; i++) {
registers[i] = NextConsecutiveRegister();
}
}
} // namespace interpreter
} // namespace internal
} // namespace v8

View File

@ -81,11 +81,6 @@ class BytecodeRegisterAllocator final {
// PrepareForConsecutiveAllocations.
Register NextConsecutiveRegister();
// Prepare consecutive register allocations and initialize an array
// of registers with the allocations.
void PrepareAndInitializeConsecutiveAllocations(Register* registers,
size_t count);
// Returns true if |reg| is allocated in this allocator.
bool RegisterIsAllocatedInThisScope(Register reg) const;