MIPS: Implement loads and calls from 'super’.

Port r24078 (b7e601f)

BUG=v8:3330
LOG=N
R=dusan.milosavljevic@imgtec.com

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24099 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 78a8f1d1
......@@ -1342,6 +1342,24 @@ void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
}
void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
Comment cnmt(masm_, "[ SuperReference ");
__ lw(LoadDescriptor::ReceiverRegister(),
MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
__ li(LoadDescriptor::NameRegister(), home_object_symbol);
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
Label done;
__ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value()));
__ CallRuntime(Runtime::kThrowNonMethodError, 0);
__ bind(&done);
}
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
TypeofState typeof_state,
Label* slow) {
......@@ -2281,6 +2299,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
......@@ -2292,6 +2311,21 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
}
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(prop->IsSuperAccess());
SuperReference* super_ref = prop->obj()->AsSuperReference();
EmitLoadHomeObject(super_ref);
__ Push(v0);
VisitForStackValue(super_ref->this_var());
__ Push(key->value());
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
......@@ -2585,9 +2619,13 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
Expression* key = expr->key();
if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj());
__ Move(LoadDescriptor::ReceiverRegister(), v0);
EmitNamedPropertyLoad(expr);
if (!expr->IsSuperAccess()) {
VisitForAccumulatorValue(expr->obj());
__ Move(LoadDescriptor::ReceiverRegister(), v0);
EmitNamedPropertyLoad(expr);
} else {
EmitNamedSuperPropertyLoad(expr);
}
PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(v0);
} else {
......@@ -2627,6 +2665,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
} else {
// Load the function from the receiver.
DCHECK(callee->IsProperty());
DCHECK(!callee->AsProperty()->IsSuperAccess());
__ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
......@@ -2640,6 +2679,44 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
}
void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
// Load the function from the receiver.
const Register scratch = a1;
SuperReference* super_ref = prop->obj()->AsSuperReference();
EmitLoadHomeObject(super_ref);
__ Push(v0);
VisitForAccumulatorValue(super_ref->this_var());
__ Push(v0);
__ lw(scratch, MemOperand(sp, kPointerSize));
__ Push(scratch, v0);
__ Push(key->value());
// Stack here:
// - home_object
// - this (receiver)
// - home_object <-- LoadFromSuper will pop here and below.
// - this (receiver)
// - key
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ sw(v0, MemOperand(sp, kPointerSize));
// Stack here:
// - target function
// - this (receiver)
EmitCall(expr, CallICState::METHOD);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
Expression* key) {
......@@ -2807,13 +2884,20 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitCall(expr);
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (property->key()->IsPropertyName()) {
EmitCallWithLoadIC(expr);
bool is_named_call = property->key()->IsPropertyName();
// super.x() is handled in EmitCallWithLoadIC.
if (property->IsSuperAccess() && is_named_call) {
EmitSuperCallWithLoadIC(expr);
} else {
EmitKeyedCallWithLoadIC(expr, property->key());
{
PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (is_named_call) {
EmitCallWithLoadIC(expr);
} else {
EmitKeyedCallWithLoadIC(expr, property->key());
}
}
} else {
DCHECK(call_type == Call::OTHER_CALL);
......
......@@ -1337,6 +1337,24 @@ void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
}
void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
Comment cnmt(masm_, "[ SuperReference ");
__ ld(LoadDescriptor::ReceiverRegister(),
MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
__ li(LoadDescriptor::NameRegister(), home_object_symbol);
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
Label done;
__ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value()));
__ CallRuntime(Runtime::kThrowNonMethodError, 0);
__ bind(&done);
}
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
TypeofState typeof_state,
Label* slow) {
......@@ -2278,6 +2296,8 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!prop->IsSuperAccess());
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
......@@ -2289,6 +2309,21 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
}
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(prop->IsSuperAccess());
SuperReference* super_ref = prop->obj()->AsSuperReference();
EmitLoadHomeObject(super_ref);
__ Push(v0);
VisitForStackValue(super_ref->this_var());
__ Push(key->value());
__ CallRuntime(Runtime::kLoadFromSuper, 3);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has register arguments receiver and key.
......@@ -2585,9 +2620,13 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
Expression* key = expr->key();
if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj());
__ Move(LoadDescriptor::ReceiverRegister(), v0);
EmitNamedPropertyLoad(expr);
if (!expr->IsSuperAccess()) {
VisitForAccumulatorValue(expr->obj());
__ Move(LoadDescriptor::ReceiverRegister(), v0);
EmitNamedPropertyLoad(expr);
} else {
EmitNamedSuperPropertyLoad(expr);
}
PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(v0);
} else {
......@@ -2627,6 +2666,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
} else {
// Load the function from the receiver.
DCHECK(callee->IsProperty());
DCHECK(!callee->AsProperty()->IsSuperAccess());
__ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
......@@ -2640,6 +2680,44 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
}
void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
// Load the function from the receiver.
const Register scratch = a1;
SuperReference* super_ref = prop->obj()->AsSuperReference();
EmitLoadHomeObject(super_ref);
__ Push(v0);
VisitForAccumulatorValue(super_ref->this_var());
__ Push(v0);
__ ld(scratch, MemOperand(sp, kPointerSize));
__ Push(scratch, v0);
__ Push(key->value());
// Stack here:
// - home_object
// - this (receiver)
// - home_object <-- LoadFromSuper will pop here and below.
// - this (receiver)
// - key
__ CallRuntime(Runtime::kLoadFromSuper, 3);
// Replace home_object with target function.
__ sd(v0, MemOperand(sp, kPointerSize));
// Stack here:
// - target function
// - this (receiver)
EmitCall(expr, CallICState::METHOD);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
Expression* key) {
......@@ -2806,13 +2884,20 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitCall(expr);
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (property->key()->IsPropertyName()) {
EmitCallWithLoadIC(expr);
bool is_named_call = property->key()->IsPropertyName();
// super.x() is handled in EmitCallWithLoadIC.
if (property->IsSuperAccess() && is_named_call) {
EmitSuperCallWithLoadIC(expr);
} else {
EmitKeyedCallWithLoadIC(expr, property->key());
{
PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (is_named_call) {
EmitCallWithLoadIC(expr);
} else {
EmitKeyedCallWithLoadIC(expr, property->key());
}
}
} else {
DCHECK(call_type == Call::OTHER_CALL);
......
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