| Index: src/mips64/full-codegen-mips64.cc
|
| diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc
|
| index 1a76c52fd29f764222388bff7d8881f29e341a0e..0aae037325bf757817bb46785556cfb6ee93f110 100644
|
| --- a/src/mips64/full-codegen-mips64.cc
|
| +++ b/src/mips64/full-codegen-mips64.cc
|
| @@ -1116,6 +1116,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
| __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
|
| __ mov(a0, v0);
|
| __ bind(&done_convert);
|
| + PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
|
| __ push(a0);
|
|
|
| // Check for proxies.
|
| @@ -1140,6 +1141,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
| __ bind(&call_runtime);
|
| __ push(a0); // Duplicate the enumerable object on the stack.
|
| __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
|
| + PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
|
|
|
| // If we got a map from the runtime call, we can do a fast
|
| // modification check. Otherwise, we got a fixed array, and we have
|
| @@ -1176,7 +1178,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
|
| __ li(a1, FeedbackVector());
|
| __ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
|
| - __ sd(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot.ToInt())));
|
| + int vector_index = FeedbackVector()->GetIndex(slot);
|
| + __ sd(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(vector_index)));
|
|
|
| __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
|
| __ ld(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
|
| @@ -1679,6 +1682,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
| FastCloneShallowObjectStub stub(isolate(), properties_count);
|
| __ CallStub(&stub);
|
| }
|
| + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
|
|
|
| // If result_saved is true the result is on top of the stack. If
|
| // result_saved is false the result is in v0.
|
| @@ -1707,6 +1711,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
| DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
|
| // Fall through.
|
| case ObjectLiteral::Property::COMPUTED:
|
| + // It is safe to use [[Put]] here because the boilerplate already
|
| + // contains computed properties with an uninitialized value.
|
| if (key->value()->IsInternalizedString()) {
|
| if (property->emit_store()) {
|
| VisitForAccumulatorValue(value);
|
| @@ -1740,7 +1746,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
| __ push(a0);
|
| VisitForStackValue(value);
|
| if (property->emit_store()) {
|
| - __ CallRuntime(Runtime::kSetPrototype, 2);
|
| + __ CallRuntime(Runtime::kInternalSetPrototype, 2);
|
| } else {
|
| __ Drop(2);
|
| }
|
| @@ -2517,10 +2523,10 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
|
| Register scratch = a2;
|
| Register scratch2 = a3;
|
| __ mov(scratch, result_register()); // home_object
|
| - __ lw(v0, MemOperand(sp, kPointerSize)); // value
|
| - __ lw(scratch2, MemOperand(sp, 0)); // this
|
| - __ sw(scratch2, MemOperand(sp, kPointerSize)); // this
|
| - __ sw(scratch, MemOperand(sp, 0)); // home_object
|
| + __ ld(v0, MemOperand(sp, kPointerSize)); // value
|
| + __ ld(scratch2, MemOperand(sp, 0)); // this
|
| + __ sd(scratch2, MemOperand(sp, kPointerSize)); // this
|
| + __ sd(scratch, MemOperand(sp, 0)); // home_object
|
| // stack: this, home_object; v0: value
|
| EmitNamedSuperPropertyStore(prop);
|
| break;
|
| @@ -2533,13 +2539,13 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
|
| VisitForAccumulatorValue(prop->key());
|
| Register scratch = a2;
|
| Register scratch2 = a3;
|
| - __ lw(scratch2, MemOperand(sp, 2 * kPointerSize)); // value
|
| + __ ld(scratch2, MemOperand(sp, 2 * kPointerSize)); // value
|
| // stack: value, this, home_object; v0: key, a3: value
|
| - __ lw(scratch, MemOperand(sp, kPointerSize)); // this
|
| - __ sw(scratch, MemOperand(sp, 2 * kPointerSize));
|
| - __ lw(scratch, MemOperand(sp, 0)); // home_object
|
| - __ sw(scratch, MemOperand(sp, kPointerSize));
|
| - __ sw(v0, MemOperand(sp, 0));
|
| + __ ld(scratch, MemOperand(sp, kPointerSize)); // this
|
| + __ sd(scratch, MemOperand(sp, 2 * kPointerSize));
|
| + __ ld(scratch, MemOperand(sp, 0)); // home_object
|
| + __ sd(scratch, MemOperand(sp, kPointerSize));
|
| + __ sd(v0, MemOperand(sp, 0));
|
| __ Move(v0, scratch2);
|
| // stack: this, home_object, key; v0: value.
|
| EmitKeyedSuperPropertyStore(prop);
|
| @@ -2935,6 +2941,14 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
|
| + DCHECK(super_ref != NULL);
|
| + __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
| + __ Push(a0);
|
| + __ CallRuntime(Runtime::kGetPrototype, 1);
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::VisitCall(Call* expr) {
|
| #ifdef DEBUG
|
| // We want to verify that RecordJSReturnSite gets called on all paths
|
| @@ -3050,10 +3064,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
| }
|
| } else if (call_type == Call::SUPER_CALL) {
|
| SuperReference* super_ref = callee->AsSuperReference();
|
| - DCHECK(super_ref != NULL);
|
| - __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
| - __ Push(a0);
|
| - __ CallRuntime(Runtime::kGetPrototype, 1);
|
| + EmitLoadSuperConstructor(super_ref);
|
| __ Push(result_register());
|
| VisitForStackValue(super_ref->this_var());
|
| EmitCall(expr, CallICState::METHOD);
|
| @@ -3085,7 +3096,12 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
| // Push constructor on the stack. If it's not a function it's used as
|
| // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
| // ignored.
|
| - VisitForStackValue(expr->expression());
|
| + if (expr->expression()->IsSuperReference()) {
|
| + EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
|
| + __ Push(result_register());
|
| + } else {
|
| + VisitForStackValue(expr->expression());
|
| + }
|
|
|
| // Push the arguments ("left-to-right") on the stack.
|
| ZoneList<Expression*>* args = expr->arguments();
|
|
|