summaryrefslogtreecommitdiff
path: root/deps/v8/src/mips64/full-codegen-mips64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/mips64/full-codegen-mips64.cc')
-rw-r--r--deps/v8/src/mips64/full-codegen-mips64.cc370
1 files changed, 248 insertions, 122 deletions
diff --git a/deps/v8/src/mips64/full-codegen-mips64.cc b/deps/v8/src/mips64/full-codegen-mips64.cc
index c69ceccec7..1d4e63e8d5 100644
--- a/deps/v8/src/mips64/full-codegen-mips64.cc
+++ b/deps/v8/src/mips64/full-codegen-mips64.cc
@@ -14,15 +14,16 @@
// places where we have to move a previous result in v0 to a0 for the
// next call: mov(a0, v0). This is not needed on the other architectures.
+#include "src/code-factory.h"
#include "src/code-stubs.h"
#include "src/codegen.h"
#include "src/compiler.h"
#include "src/debug.h"
#include "src/full-codegen.h"
+#include "src/ic/ic.h"
#include "src/isolate-inl.h"
#include "src/parser.h"
#include "src/scopes.h"
-#include "src/stub-cache.h"
#include "src/mips64/code-stubs-mips64.h"
#include "src/mips64/macro-assembler-mips64.h"
@@ -1042,7 +1043,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
- Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
+ Handle<Code> ic =
+ CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
CallIC(ic, clause->CompareId());
patch_site.EmitPatchInfo();
@@ -1173,7 +1175,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ bind(&fixed_array);
__ li(a1, FeedbackVector());
- __ li(a2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
+ __ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
__ sd(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot)));
__ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
@@ -1315,9 +1317,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
!pretenure &&
scope()->is_function_scope() &&
info->num_literals() == 0) {
- FastNewClosureStub stub(isolate(),
- info->strict_mode(),
- info->is_generator());
+ FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind());
__ li(a2, Operand(info));
__ CallStub(&stub);
} else {
@@ -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) {
@@ -1382,10 +1400,10 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
__ bind(&fast);
}
- __ ld(LoadIC::ReceiverRegister(), GlobalObjectOperand());
- __ li(LoadIC::NameRegister(), Operand(proxy->var()->name()));
+ __ ld(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
+ __ li(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
}
@@ -1473,10 +1491,10 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
Comment cmnt(masm_, "[ Global variable");
// Use inline caching. Variable name is passed in a2 and the global
// object (receiver) in a0.
- __ ld(LoadIC::ReceiverRegister(), GlobalObjectOperand());
- __ li(LoadIC::NameRegister(), Operand(var->name()));
+ __ ld(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
+ __ li(LoadDescriptor::NameRegister(), Operand(var->name()));
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
}
CallLoadIC(CONTEXTUAL);
@@ -1686,10 +1704,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(value);
- __ mov(StoreIC::ValueRegister(), result_register());
- DCHECK(StoreIC::ValueRegister().is(a0));
- __ li(StoreIC::NameRegister(), Operand(key->value()));
- __ ld(StoreIC::ReceiverRegister(), MemOperand(sp));
+ __ mov(StoreDescriptor::ValueRegister(), result_register());
+ DCHECK(StoreDescriptor::ValueRegister().is(a0));
+ __ li(StoreDescriptor::NameRegister(), Operand(key->value()));
+ __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
@@ -1853,13 +1871,19 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
- enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
+ enum LhsKind {
+ VARIABLE,
+ NAMED_PROPERTY,
+ KEYED_PROPERTY,
+ NAMED_SUPER_PROPERTY
+ };
LhsKind assign_type = VARIABLE;
Property* property = expr->target()->AsProperty();
if (property != NULL) {
assign_type = (property->key()->IsPropertyName())
- ? NAMED_PROPERTY
- : KEYED_PROPERTY;
+ ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
+ : NAMED_PROPERTY)
+ : KEYED_PROPERTY;
}
// Evaluate LHS expression.
@@ -1871,18 +1895,29 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
if (expr->is_compound()) {
// We need the receiver both on the stack and in the register.
VisitForStackValue(property->obj());
- __ ld(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
+ __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
} else {
VisitForStackValue(property->obj());
}
break;
+ case NAMED_SUPER_PROPERTY:
+ VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+ EmitLoadHomeObject(property->obj()->AsSuperReference());
+ __ Push(result_register());
+ if (expr->is_compound()) {
+ const Register scratch = a1;
+ __ ld(scratch, MemOperand(sp, kPointerSize));
+ __ Push(scratch, result_register());
+ }
+ break;
case KEYED_PROPERTY:
// We need the key and receiver on both the stack and in v0 and a1.
if (expr->is_compound()) {
VisitForStackValue(property->obj());
VisitForStackValue(property->key());
- __ ld(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize));
- __ ld(LoadIC::NameRegister(), MemOperand(sp, 0));
+ __ ld(LoadDescriptor::ReceiverRegister(),
+ MemOperand(sp, 1 * kPointerSize));
+ __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
} else {
VisitForStackValue(property->obj());
VisitForStackValue(property->key());
@@ -1903,6 +1938,10 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
EmitNamedPropertyLoad(property);
PrepareForBailoutForId(property->LoadId(), TOS_REG);
break;
+ case NAMED_SUPER_PROPERTY:
+ EmitNamedSuperPropertyLoad(property);
+ PrepareForBailoutForId(property->LoadId(), TOS_REG);
+ break;
case KEYED_PROPERTY:
EmitKeyedPropertyLoad(property);
PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1949,6 +1988,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
case NAMED_PROPERTY:
EmitNamedPropertyAssignment(expr);
break;
+ case NAMED_SUPER_PROPERTY:
+ EmitNamedSuperPropertyAssignment(expr);
+ break;
case KEYED_PROPERTY:
EmitKeyedPropertyAssignment(expr);
break;
@@ -1963,12 +2005,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
VisitForStackValue(expr->expression());
switch (expr->yield_kind()) {
- case Yield::SUSPEND:
+ case Yield::kSuspend:
// Pop value from top-of-stack slot; box result into result register.
EmitCreateIteratorResult(false);
__ push(result_register());
// Fall through.
- case Yield::INITIAL: {
+ case Yield::kInitial: {
Label suspend, continuation, post_runtime, resume;
__ jmp(&suspend);
@@ -1999,7 +2041,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
break;
}
- case Yield::FINAL: {
+ case Yield::kFinal: {
VisitForAccumulatorValue(expr->generator_object());
__ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
__ sd(a1, FieldMemOperand(result_register(),
@@ -2011,7 +2053,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
break;
}
- case Yield::DELEGATING: {
+ case Yield::kDelegating: {
VisitForStackValue(expr->generator_object());
// Initial stack layout is as follows:
@@ -2020,8 +2062,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
Label l_catch, l_try, l_suspend, l_continuation, l_resume;
Label l_next, l_call;
- Register load_receiver = LoadIC::ReceiverRegister();
- Register load_name = LoadIC::NameRegister();
+ Register load_receiver = LoadDescriptor::ReceiverRegister();
+ Register load_name = LoadDescriptor::NameRegister();
// Initial send value is undefined.
__ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
__ Branch(&l_next);
@@ -2077,10 +2119,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ ld(load_receiver, MemOperand(sp, kPointerSize));
__ ld(load_name, MemOperand(sp, 2 * kPointerSize));
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
}
- Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
__ mov(a1, a0);
@@ -2097,7 +2139,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
}
CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
@@ -2110,7 +2152,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ pop(load_receiver); // result
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
}
CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
@@ -2277,9 +2319,11 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
- __ li(LoadIC::NameRegister(), Operand(key->value()));
+ DCHECK(!prop->IsSuperAccess());
+
+ __ li(LoadDescriptor::NameRegister(), Operand(key->value()));
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
@@ -2288,12 +2332,24 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
}
+void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+ // Stack: receiver, home_object.
+ SetSourcePosition(prop->position());
+ Literal* key = prop->key()->AsLiteral();
+ DCHECK(!key->value()->IsSmi());
+ DCHECK(prop->IsSuperAccess());
+
+ __ 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.
- Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
+ Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
CallIC(ic);
} else {
@@ -2325,8 +2381,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
- BinaryOpICStub stub(isolate(), op, mode);
- CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
+ CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
@@ -2399,9 +2455,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
OverwriteMode mode) {
__ mov(a0, result_register());
__ pop(a1);
- BinaryOpICStub stub(isolate(), op, mode);
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
+ CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(v0);
}
@@ -2431,9 +2487,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
case NAMED_PROPERTY: {
__ push(result_register()); // Preserve value.
VisitForAccumulatorValue(prop->obj());
- __ mov(StoreIC::ReceiverRegister(), result_register());
- __ pop(StoreIC::ValueRegister()); // Restore value.
- __ li(StoreIC::NameRegister(),
+ __ mov(StoreDescriptor::ReceiverRegister(), result_register());
+ __ pop(StoreDescriptor::ValueRegister()); // Restore value.
+ __ li(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
CallStoreIC();
break;
@@ -2442,11 +2498,11 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ push(result_register()); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
- __ Move(KeyedStoreIC::NameRegister(), result_register());
- __ Pop(KeyedStoreIC::ValueRegister(), KeyedStoreIC::ReceiverRegister());
- Handle<Code> ic = strict_mode() == SLOPPY
- ? isolate()->builtins()->KeyedStoreIC_Initialize()
- : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
+ __ Move(StoreDescriptor::NameRegister(), result_register());
+ __ Pop(StoreDescriptor::ValueRegister(),
+ StoreDescriptor::ReceiverRegister());
+ Handle<Code> ic =
+ CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
CallIC(ic);
break;
}
@@ -2471,9 +2527,9 @@ void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
if (var->IsUnallocated()) {
// Global var, const, or let.
- __ mov(StoreIC::ValueRegister(), result_register());
- __ li(StoreIC::NameRegister(), Operand(var->name()));
- __ ld(StoreIC::ReceiverRegister(), GlobalObjectOperand());
+ __ mov(StoreDescriptor::ValueRegister(), result_register());
+ __ li(StoreDescriptor::NameRegister(), Operand(var->name()));
+ __ ld(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
} else if (op == Token::INIT_CONST_LEGACY) {
// Const initializers need a write barrier.
@@ -2546,9 +2602,10 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Record source code position before IC call.
SetSourcePosition(expr->position());
- __ mov(StoreIC::ValueRegister(), result_register());
- __ li(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value()));
- __ pop(StoreIC::ReceiverRegister());
+ __ mov(StoreDescriptor::ValueRegister(), result_register());
+ __ li(StoreDescriptor::NameRegister(),
+ Operand(prop->key()->AsLiteral()->value()));
+ __ pop(StoreDescriptor::ReceiverRegister());
CallStoreIC(expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
@@ -2556,6 +2613,24 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
}
+void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) {
+ // Assignment to named property of super.
+ // v0 : value
+ // stack : receiver ('this'), home_object
+ Property* prop = expr->target()->AsProperty();
+ DCHECK(prop != NULL);
+ Literal* key = prop->key()->AsLiteral();
+ DCHECK(key != NULL);
+
+ __ Push(v0);
+ __ Push(key->value());
+ __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+ : Runtime::kStoreToSuper_Sloppy),
+ 4);
+ context()->Plug(v0);
+}
+
+
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
@@ -2566,13 +2641,11 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// - a0 is the value,
// - a1 is the key,
// - a2 is the receiver.
- __ mov(KeyedStoreIC::ValueRegister(), result_register());
- __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
- DCHECK(KeyedStoreIC::ValueRegister().is(a0));
+ __ mov(StoreDescriptor::ValueRegister(), result_register());
+ __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
+ DCHECK(StoreDescriptor::ValueRegister().is(a0));
- Handle<Code> ic = strict_mode() == SLOPPY
- ? isolate()->builtins()->KeyedStoreIC_Initialize()
- : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
+ Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
CallIC(ic, expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
@@ -2585,16 +2658,23 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
Expression* key = expr->key();
if (key->IsPropertyName()) {
- VisitForAccumulatorValue(expr->obj());
- __ Move(LoadIC::ReceiverRegister(), v0);
- EmitNamedPropertyLoad(expr);
+ if (!expr->IsSuperAccess()) {
+ VisitForAccumulatorValue(expr->obj());
+ __ Move(LoadDescriptor::ReceiverRegister(), v0);
+ EmitNamedPropertyLoad(expr);
+ } else {
+ VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+ EmitLoadHomeObject(expr->obj()->AsSuperReference());
+ __ Push(result_register());
+ EmitNamedSuperPropertyLoad(expr);
+ }
PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(v0);
} else {
VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key());
- __ Move(LoadIC::NameRegister(), v0);
- __ pop(LoadIC::ReceiverRegister());
+ __ Move(LoadDescriptor::NameRegister(), v0);
+ __ pop(LoadDescriptor::ReceiverRegister());
EmitKeyedPropertyLoad(expr);
context()->Plug(v0);
}
@@ -2612,12 +2692,11 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
- CallIC::CallType call_type = callee->IsVariableProxy()
- ? CallIC::FUNCTION
- : CallIC::METHOD;
+ CallICState::CallType call_type =
+ callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
// Get the target function.
- if (call_type == CallIC::FUNCTION) {
+ if (call_type == CallICState::FUNCTION) {
{ StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy());
PrepareForBailout(callee, NO_REGISTERS);
@@ -2628,7 +2707,8 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
} else {
// Load the function from the receiver.
DCHECK(callee->IsProperty());
- __ ld(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
+ DCHECK(!callee->AsProperty()->IsSuperAccess());
+ __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver.
@@ -2641,6 +2721,42 @@ 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);
+ __ mov(scratch, v0);
+ VisitForAccumulatorValue(super_ref->this_var());
+ __ Push(scratch, v0, v0, scratch);
+ __ Push(key->value());
+
+ // Stack here:
+ // - home_object
+ // - this (receiver)
+ // - this (receiver) <-- LoadFromSuper will pop here and below.
+ // - home_object
+ // - 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) {
@@ -2651,8 +2767,8 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
// Load the function from the receiver.
DCHECK(callee->IsProperty());
- __ ld(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
- __ Move(LoadIC::NameRegister(), v0);
+ __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+ __ Move(LoadDescriptor::NameRegister(), v0);
EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
@@ -2661,11 +2777,11 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
__ push(at);
__ sd(v0, MemOperand(sp, kPointerSize));
- EmitCall(expr, CallIC::METHOD);
+ EmitCall(expr, CallICState::METHOD);
}
-void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
@@ -2807,13 +2923,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);
@@ -3314,7 +3437,7 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
// Functions have class 'Function'.
__ bind(&function);
- __ LoadRoot(v0, Heap::kfunction_class_stringRootIndex);
+ __ LoadRoot(v0, Heap::kFunction_stringRootIndex);
__ jmp(&done);
// Objects with a non-function constructor have class 'Object'.
@@ -3435,9 +3558,9 @@ void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
Register index = a1;
Register value = a2;
- VisitForStackValue(args->at(1)); // index
- VisitForStackValue(args->at(2)); // value
- VisitForAccumulatorValue(args->at(0)); // string
+ VisitForStackValue(args->at(0)); // index
+ VisitForStackValue(args->at(1)); // value
+ VisitForAccumulatorValue(args->at(2)); // string
__ Pop(index, value);
if (FLAG_debug_code) {
@@ -3472,9 +3595,9 @@ void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
Register index = a1;
Register value = a2;
- VisitForStackValue(args->at(1)); // index
- VisitForStackValue(args->at(2)); // value
- VisitForAccumulatorValue(args->at(0)); // string
+ VisitForStackValue(args->at(0)); // index
+ VisitForStackValue(args->at(1)); // value
+ VisitForAccumulatorValue(args->at(2)); // string
__ Pop(index, value);
if (FLAG_debug_code) {
@@ -3835,7 +3958,7 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
}
-void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
+void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) {
Label bailout, done, one_char_separator, long_separator,
non_trivial_array, not_size_one_array, loop,
empty_separator_loop, one_char_separator_loop,
@@ -3885,7 +4008,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
__ ld(elements, FieldMemOperand(array, JSArray::kElementsOffset));
array = no_reg; // End of array's live range.
- // Check that all array elements are sequential ASCII strings, and
+ // Check that all array elements are sequential one-byte strings, and
// accumulate the sum of their lengths, as a smi-encoded value.
__ mov(string_length, zero_reg);
__ Daddu(element,
@@ -3901,8 +4024,8 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// element: Current array element.
// elements_end: Array end.
if (generate_debug_code_) {
- __ Assert(gt, kNoEmptyArraysHereInEmitFastAsciiArrayJoin,
- array_length, Operand(zero_reg));
+ __ Assert(gt, kNoEmptyArraysHereInEmitFastOneByteArrayJoin, array_length,
+ Operand(zero_reg));
}
__ bind(&loop);
__ ld(string, MemOperand(element));
@@ -3910,7 +4033,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
__ JumpIfSmi(string, &bailout);
__ ld(scratch1, FieldMemOperand(string, HeapObject::kMapOffset));
__ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
- __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout);
+ __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout);
__ ld(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset));
__ AdduAndCheckForOverflow(string_length, string_length, scratch1, scratch3);
__ BranchOnOverflow(&bailout, scratch3);
@@ -3929,11 +4052,11 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// string_length: Sum of string lengths (smi).
// elements: FixedArray of strings.
- // Check that the separator is a flat ASCII string.
+ // Check that the separator is a flat one-byte string.
__ JumpIfSmi(separator, &bailout);
__ ld(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset));
__ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
- __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout);
+ __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout);
// Add (separator length times array_length) - separator length to the
// string_length to get the length of the result string. array_length is not
@@ -3961,12 +4084,8 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// separator: Separator string
// string_length: Length of result string (not smi)
// array_length: Length of the array.
- __ AllocateAsciiString(result,
- string_length,
- scratch1,
- scratch2,
- elements_end,
- &bailout);
+ __ AllocateOneByteString(result, string_length, scratch1, scratch2,
+ elements_end, &bailout);
// Prepare for looping. Set up elements_end to end of the array. Set
// result_pos to the position of the result where to write the first
// character.
@@ -4005,7 +4124,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// One-character separator case.
__ bind(&one_char_separator);
- // Replace separator with its ASCII character value.
+ // Replace separator with its one-byte character value.
__ lbu(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize));
// Jump into the loop after the code that copies the separator, so the first
// element is not preceded by a separator.
@@ -4016,7 +4135,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
// result_pos: the position to which we are currently copying characters.
// element: Current array element.
// elements_end: Array end.
- // separator: Single separator ASCII char (in lower byte).
+ // separator: Single separator one-byte char (in lower byte).
// Copy the separator character to the result.
__ sb(separator, MemOperand(result_pos));
@@ -4096,15 +4215,15 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
if (expr->is_jsruntime()) {
// Push the builtins object as the receiver.
- Register receiver = LoadIC::ReceiverRegister();
+ Register receiver = LoadDescriptor::ReceiverRegister();
__ ld(receiver, GlobalObjectOperand());
__ ld(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
__ push(receiver);
// Load the function from the receiver.
- __ li(LoadIC::NameRegister(), Operand(expr->name()));
+ __ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
@@ -4271,6 +4390,11 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (prop != NULL) {
assign_type =
(prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
+ if (prop->IsSuperAccess()) {
+ // throw exception.
+ VisitSuperReference(prop->obj()->AsSuperReference());
+ return;
+ }
}
// Evaluate expression and get value.
@@ -4287,13 +4411,14 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == NAMED_PROPERTY) {
// Put the object both on the stack and in the register.
VisitForStackValue(prop->obj());
- __ ld(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
+ __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(prop);
} else {
VisitForStackValue(prop->obj());
VisitForStackValue(prop->key());
- __ ld(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize));
- __ ld(LoadIC::NameRegister(), MemOperand(sp, 0));
+ __ ld(LoadDescriptor::ReceiverRegister(),
+ MemOperand(sp, 1 * kPointerSize));
+ __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
EmitKeyedPropertyLoad(prop);
}
}
@@ -4376,8 +4501,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Record position before stub call.
SetSourcePosition(expr->position());
- BinaryOpICStub stub(isolate(), Token::ADD, NO_OVERWRITE);
- CallIC(stub.GetCode(), expr->CountBinOpFeedbackId());
+ Handle<Code> code =
+ CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code();
+ CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4404,10 +4530,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
break;
case NAMED_PROPERTY: {
- __ mov(StoreIC::ValueRegister(), result_register());
- __ li(StoreIC::NameRegister(),
+ __ mov(StoreDescriptor::ValueRegister(), result_register());
+ __ li(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
- __ pop(StoreIC::ReceiverRegister());
+ __ pop(StoreDescriptor::ReceiverRegister());
CallStoreIC(expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -4420,11 +4546,11 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
break;
}
case KEYED_PROPERTY: {
- __ mov(KeyedStoreIC::ValueRegister(), result_register());
- __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
- Handle<Code> ic = strict_mode() == SLOPPY
- ? isolate()->builtins()->KeyedStoreIC_Initialize()
- : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
+ __ mov(StoreDescriptor::ValueRegister(), result_register());
+ __ Pop(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister());
+ Handle<Code> ic =
+ CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
CallIC(ic, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -4446,10 +4572,10 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
VariableProxy* proxy = expr->AsVariableProxy();
if (proxy != NULL && proxy->var()->IsUnallocated()) {
Comment cmnt(masm_, "[ Global variable");
- __ ld(LoadIC::ReceiverRegister(), GlobalObjectOperand());
- __ li(LoadIC::NameRegister(), Operand(proxy->name()));
+ __ ld(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
+ __ li(LoadDescriptor::NameRegister(), Operand(proxy->name()));
if (FLAG_vector_ics) {
- __ li(LoadIC::SlotRegister(),
+ __ li(VectorLoadICDescriptor::SlotRegister(),
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
}
// Use a regular load, not a contextual load, to avoid a reference
@@ -4609,7 +4735,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
- Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
+ Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code();
CallIC(ic, expr->CompareOperationFeedbackId());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);