From ffd7362fcc47d1c2418ba2b383af9ef9b66dcb84 Mon Sep 17 00:00:00 2001 From: "balazs.kilvady@imgtec.com" Date: Fri, 19 Sep 2014 17:25:46 +0000 Subject: [PATCH] =?utf8?q?MIPS:=20Implement=20loads=20and=20calls=20from?= =?utf8?q?=20'super=E2=80=99.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/mips/full-codegen-mips.cc | 102 +++++++++++++++++++++++++++++++++---- src/mips64/full-codegen-mips64.cc | 103 ++++++++++++++++++++++++++++++++++---- 2 files changed, 187 insertions(+), 18 deletions(-) diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 53915c5..568b8bd 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -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 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 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); diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc index 291e4ab..5c26f16 100644 --- a/src/mips64/full-codegen-mips64.cc +++ b/src/mips64/full-codegen-mips64.cc @@ -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 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); -- 2.7.4