Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Side by Side Diff: src/full-codegen/mips64/full-codegen-mips64.cc

Issue 1706283002: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Turn off verification. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/mips/full-codegen-mips.cc ('k') | src/full-codegen/ppc/full-codegen-ppc.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 // Note on Mips implementation: 7 // Note on Mips implementation:
8 // 8 //
9 // The result_register() for mips is the 'v0' register, which is defined 9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first 10 // by the ABI to contain function return values. However, the first
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 // MANUAL indicates that the scope shouldn't actually generate code to set up 131 // MANUAL indicates that the scope shouldn't actually generate code to set up
132 // the frame (that is done below). 132 // the frame (that is done below).
133 FrameScope frame_scope(masm_, StackFrame::MANUAL); 133 FrameScope frame_scope(masm_, StackFrame::MANUAL);
134 info->set_prologue_offset(masm_->pc_offset()); 134 info->set_prologue_offset(masm_->pc_offset());
135 __ Prologue(info->GeneratePreagedPrologue()); 135 __ Prologue(info->GeneratePreagedPrologue());
136 136
137 { Comment cmnt(masm_, "[ Allocate locals"); 137 { Comment cmnt(masm_, "[ Allocate locals");
138 int locals_count = info->scope()->num_stack_slots(); 138 int locals_count = info->scope()->num_stack_slots();
139 // Generators allocate locals, if any, in context slots. 139 // Generators allocate locals, if any, in context slots.
140 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 140 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
141 OperandStackDepthIncrement(locals_count);
141 if (locals_count > 0) { 142 if (locals_count > 0) {
142 if (locals_count >= 128) { 143 if (locals_count >= 128) {
143 Label ok; 144 Label ok;
144 __ Dsubu(t1, sp, Operand(locals_count * kPointerSize)); 145 __ Dsubu(t1, sp, Operand(locals_count * kPointerSize));
145 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); 146 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
146 __ Branch(&ok, hs, t1, Operand(a2)); 147 __ Branch(&ok, hs, t1, Operand(a2));
147 __ CallRuntime(Runtime::kThrowStackOverflow); 148 __ CallRuntime(Runtime::kThrowStackOverflow);
148 __ bind(&ok); 149 __ bind(&ok);
149 } 150 }
150 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex); 151 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 masm_->Daddu(sp, sp, Operand(sp_delta)); 459 masm_->Daddu(sp, sp, Operand(sp_delta));
459 masm_->Jump(ra); 460 masm_->Jump(ra);
460 } 461 }
461 } 462 }
462 } 463 }
463 464
464 465
465 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 466 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
466 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 467 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
467 codegen()->GetVar(result_register(), var); 468 codegen()->GetVar(result_register(), var);
468 __ push(result_register()); 469 codegen()->PushOperand(result_register());
469 } 470 }
470 471
471 472
472 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 473 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
473 } 474 }
474 475
475 476
476 void FullCodeGenerator::AccumulatorValueContext::Plug( 477 void FullCodeGenerator::AccumulatorValueContext::Plug(
477 Heap::RootListIndex index) const { 478 Heap::RootListIndex index) const {
478 __ LoadRoot(result_register(), index); 479 __ LoadRoot(result_register(), index);
479 } 480 }
480 481
481 482
482 void FullCodeGenerator::StackValueContext::Plug( 483 void FullCodeGenerator::StackValueContext::Plug(
483 Heap::RootListIndex index) const { 484 Heap::RootListIndex index) const {
484 __ LoadRoot(result_register(), index); 485 __ LoadRoot(result_register(), index);
485 __ push(result_register()); 486 codegen()->PushOperand(result_register());
486 } 487 }
487 488
488 489
489 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 490 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
490 codegen()->PrepareForBailoutBeforeSplit(condition(), 491 codegen()->PrepareForBailoutBeforeSplit(condition(),
491 true, 492 true,
492 true_label_, 493 true_label_,
493 false_label_); 494 false_label_);
494 if (index == Heap::kUndefinedValueRootIndex || 495 if (index == Heap::kUndefinedValueRootIndex ||
495 index == Heap::kNullValueRootIndex || 496 index == Heap::kNullValueRootIndex ||
(...skipping 14 matching lines...) Expand all
510 511
511 void FullCodeGenerator::AccumulatorValueContext::Plug( 512 void FullCodeGenerator::AccumulatorValueContext::Plug(
512 Handle<Object> lit) const { 513 Handle<Object> lit) const {
513 __ li(result_register(), Operand(lit)); 514 __ li(result_register(), Operand(lit));
514 } 515 }
515 516
516 517
517 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 518 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
518 // Immediates cannot be pushed directly. 519 // Immediates cannot be pushed directly.
519 __ li(result_register(), Operand(lit)); 520 __ li(result_register(), Operand(lit));
520 __ push(result_register()); 521 codegen()->PushOperand(result_register());
521 } 522 }
522 523
523 524
524 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 525 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
525 codegen()->PrepareForBailoutBeforeSplit(condition(), 526 codegen()->PrepareForBailoutBeforeSplit(condition(),
526 true, 527 true,
527 true_label_, 528 true_label_,
528 false_label_); 529 false_label_);
529 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); 530 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject());
530 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 531 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
(...skipping 13 matching lines...) Expand all
544 if (true_label_ != fall_through_) __ Branch(true_label_); 545 if (true_label_ != fall_through_) __ Branch(true_label_);
545 } 546 }
546 } else { 547 } else {
547 // For simplicity we always test the accumulator register. 548 // For simplicity we always test the accumulator register.
548 __ li(result_register(), Operand(lit)); 549 __ li(result_register(), Operand(lit));
549 codegen()->DoTest(this); 550 codegen()->DoTest(this);
550 } 551 }
551 } 552 }
552 553
553 554
554 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
555 Register reg) const {
556 DCHECK(count > 0);
557 __ Drop(count);
558 }
559
560
561 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
562 int count,
563 Register reg) const {
564 DCHECK(count > 0);
565 __ Drop(count);
566 __ Move(result_register(), reg);
567 }
568
569
570 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 555 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
571 Register reg) const { 556 Register reg) const {
572 DCHECK(count > 0); 557 DCHECK(count > 0);
573 if (count > 1) __ Drop(count - 1); 558 if (count > 1) codegen()->DropOperands(count - 1);
574 __ sd(reg, MemOperand(sp, 0)); 559 __ sd(reg, MemOperand(sp, 0));
575 } 560 }
576 561
577 562
578 void FullCodeGenerator::TestContext::DropAndPlug(int count,
579 Register reg) const {
580 DCHECK(count > 0);
581 // For simplicity we always test the accumulator register.
582 __ Drop(count);
583 __ Move(result_register(), reg);
584 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
585 codegen()->DoTest(this);
586 }
587
588
589 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 563 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
590 Label* materialize_false) const { 564 Label* materialize_false) const {
591 DCHECK(materialize_true == materialize_false); 565 DCHECK(materialize_true == materialize_false);
592 __ bind(materialize_true); 566 __ bind(materialize_true);
593 } 567 }
594 568
595 569
596 void FullCodeGenerator::AccumulatorValueContext::Plug( 570 void FullCodeGenerator::AccumulatorValueContext::Plug(
597 Label* materialize_true, 571 Label* materialize_true,
598 Label* materialize_false) const { 572 Label* materialize_false) const {
599 Label done; 573 Label done;
600 __ bind(materialize_true); 574 __ bind(materialize_true);
601 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); 575 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
602 __ Branch(&done); 576 __ Branch(&done);
603 __ bind(materialize_false); 577 __ bind(materialize_false);
604 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); 578 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
605 __ bind(&done); 579 __ bind(&done);
606 } 580 }
607 581
608 582
609 void FullCodeGenerator::StackValueContext::Plug( 583 void FullCodeGenerator::StackValueContext::Plug(
610 Label* materialize_true, 584 Label* materialize_true,
611 Label* materialize_false) const { 585 Label* materialize_false) const {
586 codegen()->OperandStackDepthIncrement(1);
612 Label done; 587 Label done;
613 __ bind(materialize_true); 588 __ bind(materialize_true);
614 __ LoadRoot(at, Heap::kTrueValueRootIndex); 589 __ LoadRoot(at, Heap::kTrueValueRootIndex);
615 // Push the value as the following branch can clobber at in long branch mode. 590 // Push the value as the following branch can clobber at in long branch mode.
616 __ push(at); 591 __ push(at);
617 __ Branch(&done); 592 __ Branch(&done);
618 __ bind(materialize_false); 593 __ bind(materialize_false);
619 __ LoadRoot(at, Heap::kFalseValueRootIndex); 594 __ LoadRoot(at, Heap::kFalseValueRootIndex);
620 __ push(at); 595 __ push(at);
621 __ bind(&done); 596 __ bind(&done);
(...skipping 11 matching lines...) Expand all
633 Heap::RootListIndex value_root_index = 608 Heap::RootListIndex value_root_index =
634 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 609 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
635 __ LoadRoot(result_register(), value_root_index); 610 __ LoadRoot(result_register(), value_root_index);
636 } 611 }
637 612
638 613
639 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 614 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
640 Heap::RootListIndex value_root_index = 615 Heap::RootListIndex value_root_index =
641 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 616 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
642 __ LoadRoot(at, value_root_index); 617 __ LoadRoot(at, value_root_index);
643 __ push(at); 618 codegen()->PushOperand(at);
644 } 619 }
645 620
646 621
647 void FullCodeGenerator::TestContext::Plug(bool flag) const { 622 void FullCodeGenerator::TestContext::Plug(bool flag) const {
648 codegen()->PrepareForBailoutBeforeSplit(condition(), 623 codegen()->PrepareForBailoutBeforeSplit(condition(),
649 true, 624 true,
650 true_label_, 625 true_label_,
651 false_label_); 626 false_label_);
652 if (flag) { 627 if (flag) {
653 if (true_label_ != fall_through_) __ Branch(true_label_); 628 if (true_label_ != fall_through_) __ Branch(true_label_);
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 kDontSaveFPRegs, 855 kDontSaveFPRegs,
881 EMIT_REMEMBERED_SET, 856 EMIT_REMEMBERED_SET,
882 OMIT_SMI_CHECK); 857 OMIT_SMI_CHECK);
883 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 858 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
884 break; 859 break;
885 } 860 }
886 861
887 case VariableLocation::LOOKUP: { 862 case VariableLocation::LOOKUP: {
888 Comment cmnt(masm_, "[ FunctionDeclaration"); 863 Comment cmnt(masm_, "[ FunctionDeclaration");
889 __ li(a2, Operand(variable->name())); 864 __ li(a2, Operand(variable->name()));
890 __ Push(a2); 865 PushOperand(a2);
891 // Push initial value for function declaration. 866 // Push initial value for function declaration.
892 VisitForStackValue(declaration->fun()); 867 VisitForStackValue(declaration->fun());
893 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 868 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
894 __ CallRuntime(Runtime::kDeclareLookupSlot); 869 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
895 break; 870 break;
896 } 871 }
897 } 872 }
898 } 873 }
899 874
900 875
901 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 876 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
902 // Call the runtime to declare the globals. 877 // Call the runtime to declare the globals.
903 __ li(a1, Operand(pairs)); 878 __ li(a1, Operand(pairs));
904 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 879 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 __ bind(&skip); 956 __ bind(&skip);
982 957
983 __ Branch(&next_test, ne, v0, Operand(zero_reg)); 958 __ Branch(&next_test, ne, v0, Operand(zero_reg));
984 __ Drop(1); // Switch value is no longer needed. 959 __ Drop(1); // Switch value is no longer needed.
985 __ Branch(clause->body_target()); 960 __ Branch(clause->body_target());
986 } 961 }
987 962
988 // Discard the test value and jump to the default if present, otherwise to 963 // Discard the test value and jump to the default if present, otherwise to
989 // the end of the statement. 964 // the end of the statement.
990 __ bind(&next_test); 965 __ bind(&next_test);
991 __ Drop(1); // Switch value is no longer needed. 966 DropOperands(1); // Switch value is no longer needed.
992 if (default_clause == NULL) { 967 if (default_clause == NULL) {
993 __ Branch(nested_statement.break_label()); 968 __ Branch(nested_statement.break_label());
994 } else { 969 } else {
995 __ Branch(default_clause->body_target()); 970 __ Branch(default_clause->body_target());
996 } 971 }
997 972
998 // Compile all the case bodies. 973 // Compile all the case bodies.
999 for (int i = 0; i < clauses->length(); i++) { 974 for (int i = 0; i < clauses->length(); i++) {
1000 Comment cmnt(masm_, "[ Case body"); 975 Comment cmnt(masm_, "[ Case body");
1001 CaseClause* clause = clauses->at(i); 976 CaseClause* clause = clauses->at(i);
(...skipping 15 matching lines...) Expand all
1017 992
1018 Label loop, exit; 993 Label loop, exit;
1019 ForIn loop_statement(this, stmt); 994 ForIn loop_statement(this, stmt);
1020 increment_loop_depth(); 995 increment_loop_depth();
1021 996
1022 // Get the object to enumerate over. If the object is null or undefined, skip 997 // Get the object to enumerate over. If the object is null or undefined, skip
1023 // over the loop. See ECMA-262 version 5, section 12.6.4. 998 // over the loop. See ECMA-262 version 5, section 12.6.4.
1024 SetExpressionAsStatementPosition(stmt->enumerable()); 999 SetExpressionAsStatementPosition(stmt->enumerable());
1025 VisitForAccumulatorValue(stmt->enumerable()); 1000 VisitForAccumulatorValue(stmt->enumerable());
1026 __ mov(a0, result_register()); 1001 __ mov(a0, result_register());
1002 OperandStackDepthIncrement(ForIn::kElementCount);
1027 1003
1028 // If the object is null or undefined, skip over the loop, otherwise convert 1004 // If the object is null or undefined, skip over the loop, otherwise convert
1029 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 1005 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
1030 Label convert, done_convert; 1006 Label convert, done_convert;
1031 __ JumpIfSmi(a0, &convert); 1007 __ JumpIfSmi(a0, &convert);
1032 __ GetObjectType(a0, a1, a1); 1008 __ GetObjectType(a0, a1, a1);
1033 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, 1009 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1,
1034 Operand(FIRST_JS_RECEIVER_TYPE)); 1010 Operand(FIRST_JS_RECEIVER_TYPE));
1035 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. 1011 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot.
1036 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); 1012 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at));
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 __ bind(loop_statement.continue_label()); 1153 __ bind(loop_statement.continue_label());
1178 __ pop(a0); 1154 __ pop(a0);
1179 __ Daddu(a0, a0, Operand(Smi::FromInt(1))); 1155 __ Daddu(a0, a0, Operand(Smi::FromInt(1)));
1180 __ push(a0); 1156 __ push(a0);
1181 1157
1182 EmitBackEdgeBookkeeping(stmt, &loop); 1158 EmitBackEdgeBookkeeping(stmt, &loop);
1183 __ Branch(&loop); 1159 __ Branch(&loop);
1184 1160
1185 // Remove the pointers stored on the stack. 1161 // Remove the pointers stored on the stack.
1186 __ bind(loop_statement.break_label()); 1162 __ bind(loop_statement.break_label());
1187 __ Drop(5); 1163 DropOperands(5);
1188 1164
1189 // Exit and decrement the loop depth. 1165 // Exit and decrement the loop depth.
1190 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1166 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1191 __ bind(&exit); 1167 __ bind(&exit);
1192 decrement_loop_depth(); 1168 decrement_loop_depth();
1193 } 1169 }
1194 1170
1195 1171
1196 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1172 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1197 bool pretenure) { 1173 bool pretenure) {
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 FastCloneRegExpStub stub(isolate()); 1429 FastCloneRegExpStub stub(isolate());
1454 __ CallStub(&stub); 1430 __ CallStub(&stub);
1455 context()->Plug(v0); 1431 context()->Plug(v0);
1456 } 1432 }
1457 1433
1458 1434
1459 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1435 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1460 Expression* expression = (property == NULL) ? NULL : property->value(); 1436 Expression* expression = (property == NULL) ? NULL : property->value();
1461 if (expression == NULL) { 1437 if (expression == NULL) {
1462 __ LoadRoot(a1, Heap::kNullValueRootIndex); 1438 __ LoadRoot(a1, Heap::kNullValueRootIndex);
1463 __ push(a1); 1439 PushOperand(a1);
1464 } else { 1440 } else {
1465 VisitForStackValue(expression); 1441 VisitForStackValue(expression);
1466 if (NeedsHomeObject(expression)) { 1442 if (NeedsHomeObject(expression)) {
1467 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1443 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1468 property->kind() == ObjectLiteral::Property::SETTER); 1444 property->kind() == ObjectLiteral::Property::SETTER);
1469 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1445 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1470 EmitSetHomeObject(expression, offset, property->GetSlot()); 1446 EmitSetHomeObject(expression, offset, property->GetSlot());
1471 } 1447 }
1472 } 1448 }
1473 } 1449 }
(...skipping 23 matching lines...) Expand all
1497 AccessorTable accessor_table(zone()); 1473 AccessorTable accessor_table(zone());
1498 int property_index = 0; 1474 int property_index = 0;
1499 for (; property_index < expr->properties()->length(); property_index++) { 1475 for (; property_index < expr->properties()->length(); property_index++) {
1500 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1476 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1501 if (property->is_computed_name()) break; 1477 if (property->is_computed_name()) break;
1502 if (property->IsCompileTimeValue()) continue; 1478 if (property->IsCompileTimeValue()) continue;
1503 1479
1504 Literal* key = property->key()->AsLiteral(); 1480 Literal* key = property->key()->AsLiteral();
1505 Expression* value = property->value(); 1481 Expression* value = property->value();
1506 if (!result_saved) { 1482 if (!result_saved) {
1507 __ push(v0); // Save result on stack. 1483 PushOperand(v0); // Save result on stack.
1508 result_saved = true; 1484 result_saved = true;
1509 } 1485 }
1510 switch (property->kind()) { 1486 switch (property->kind()) {
1511 case ObjectLiteral::Property::CONSTANT: 1487 case ObjectLiteral::Property::CONSTANT:
1512 UNREACHABLE(); 1488 UNREACHABLE();
1513 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1489 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1514 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1490 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1515 // Fall through. 1491 // Fall through.
1516 case ObjectLiteral::Property::COMPUTED: 1492 case ObjectLiteral::Property::COMPUTED:
1517 // It is safe to use [[Put]] here because the boilerplate already 1493 // It is safe to use [[Put]] here because the boilerplate already
(...skipping 12 matching lines...) Expand all
1530 if (NeedsHomeObject(value)) { 1506 if (NeedsHomeObject(value)) {
1531 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1507 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1532 } 1508 }
1533 } else { 1509 } else {
1534 VisitForEffect(value); 1510 VisitForEffect(value);
1535 } 1511 }
1536 break; 1512 break;
1537 } 1513 }
1538 // Duplicate receiver on stack. 1514 // Duplicate receiver on stack.
1539 __ ld(a0, MemOperand(sp)); 1515 __ ld(a0, MemOperand(sp));
1540 __ push(a0); 1516 PushOperand(a0);
1541 VisitForStackValue(key); 1517 VisitForStackValue(key);
1542 VisitForStackValue(value); 1518 VisitForStackValue(value);
1543 if (property->emit_store()) { 1519 if (property->emit_store()) {
1544 if (NeedsHomeObject(value)) { 1520 if (NeedsHomeObject(value)) {
1545 EmitSetHomeObject(value, 2, property->GetSlot()); 1521 EmitSetHomeObject(value, 2, property->GetSlot());
1546 } 1522 }
1547 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. 1523 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes.
1548 __ push(a0); 1524 PushOperand(a0);
1549 __ CallRuntime(Runtime::kSetProperty); 1525 CallRuntimeWithOperands(Runtime::kSetProperty);
1550 } else { 1526 } else {
1551 __ Drop(3); 1527 DropOperands(3);
1552 } 1528 }
1553 break; 1529 break;
1554 case ObjectLiteral::Property::PROTOTYPE: 1530 case ObjectLiteral::Property::PROTOTYPE:
1555 // Duplicate receiver on stack. 1531 // Duplicate receiver on stack.
1556 __ ld(a0, MemOperand(sp)); 1532 __ ld(a0, MemOperand(sp));
1557 __ push(a0); 1533 PushOperand(a0);
1558 VisitForStackValue(value); 1534 VisitForStackValue(value);
1559 DCHECK(property->emit_store()); 1535 DCHECK(property->emit_store());
1560 __ CallRuntime(Runtime::kInternalSetPrototype); 1536 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1561 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1537 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1562 NO_REGISTERS); 1538 NO_REGISTERS);
1563 break; 1539 break;
1564 case ObjectLiteral::Property::GETTER: 1540 case ObjectLiteral::Property::GETTER:
1565 if (property->emit_store()) { 1541 if (property->emit_store()) {
1566 accessor_table.lookup(key)->second->getter = property; 1542 accessor_table.lookup(key)->second->getter = property;
1567 } 1543 }
1568 break; 1544 break;
1569 case ObjectLiteral::Property::SETTER: 1545 case ObjectLiteral::Property::SETTER:
1570 if (property->emit_store()) { 1546 if (property->emit_store()) {
1571 accessor_table.lookup(key)->second->setter = property; 1547 accessor_table.lookup(key)->second->setter = property;
1572 } 1548 }
1573 break; 1549 break;
1574 } 1550 }
1575 } 1551 }
1576 1552
1577 // Emit code to define accessors, using only a single call to the runtime for 1553 // Emit code to define accessors, using only a single call to the runtime for
1578 // each pair of corresponding getters and setters. 1554 // each pair of corresponding getters and setters.
1579 for (AccessorTable::Iterator it = accessor_table.begin(); 1555 for (AccessorTable::Iterator it = accessor_table.begin();
1580 it != accessor_table.end(); 1556 it != accessor_table.end();
1581 ++it) { 1557 ++it) {
1582 __ ld(a0, MemOperand(sp)); // Duplicate receiver. 1558 __ ld(a0, MemOperand(sp)); // Duplicate receiver.
1583 __ push(a0); 1559 PushOperand(a0);
1584 VisitForStackValue(it->first); 1560 VisitForStackValue(it->first);
1585 EmitAccessor(it->second->getter); 1561 EmitAccessor(it->second->getter);
1586 EmitAccessor(it->second->setter); 1562 EmitAccessor(it->second->setter);
1587 __ li(a0, Operand(Smi::FromInt(NONE))); 1563 __ li(a0, Operand(Smi::FromInt(NONE)));
1588 __ push(a0); 1564 PushOperand(a0);
1589 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1565 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1590 } 1566 }
1591 1567
1592 // Object literals have two parts. The "static" part on the left contains no 1568 // Object literals have two parts. The "static" part on the left contains no
1593 // computed property names, and so we can compute its map ahead of time; see 1569 // computed property names, and so we can compute its map ahead of time; see
1594 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1570 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1595 // starts with the first computed property name, and continues with all 1571 // starts with the first computed property name, and continues with all
1596 // properties to its right. All the code from above initializes the static 1572 // properties to its right. All the code from above initializes the static
1597 // component of the object literal, and arranges for the map of the result to 1573 // component of the object literal, and arranges for the map of the result to
1598 // reflect the static order in which the keys appear. For the dynamic 1574 // reflect the static order in which the keys appear. For the dynamic
1599 // properties, we compile them into a series of "SetOwnProperty" runtime 1575 // properties, we compile them into a series of "SetOwnProperty" runtime
1600 // calls. This will preserve insertion order. 1576 // calls. This will preserve insertion order.
1601 for (; property_index < expr->properties()->length(); property_index++) { 1577 for (; property_index < expr->properties()->length(); property_index++) {
1602 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1578 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1603 1579
1604 Expression* value = property->value(); 1580 Expression* value = property->value();
1605 if (!result_saved) { 1581 if (!result_saved) {
1606 __ push(v0); // Save result on the stack 1582 PushOperand(v0); // Save result on the stack
1607 result_saved = true; 1583 result_saved = true;
1608 } 1584 }
1609 1585
1610 __ ld(a0, MemOperand(sp)); // Duplicate receiver. 1586 __ ld(a0, MemOperand(sp)); // Duplicate receiver.
1611 __ push(a0); 1587 PushOperand(a0);
1612 1588
1613 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1589 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1614 DCHECK(!property->is_computed_name()); 1590 DCHECK(!property->is_computed_name());
1615 VisitForStackValue(value); 1591 VisitForStackValue(value);
1616 DCHECK(property->emit_store()); 1592 DCHECK(property->emit_store());
1617 __ CallRuntime(Runtime::kInternalSetPrototype); 1593 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1618 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1594 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1619 NO_REGISTERS); 1595 NO_REGISTERS);
1620 } else { 1596 } else {
1621 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1597 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1622 VisitForStackValue(value); 1598 VisitForStackValue(value);
1623 if (NeedsHomeObject(value)) { 1599 if (NeedsHomeObject(value)) {
1624 EmitSetHomeObject(value, 2, property->GetSlot()); 1600 EmitSetHomeObject(value, 2, property->GetSlot());
1625 } 1601 }
1626 1602
1627 switch (property->kind()) { 1603 switch (property->kind()) {
1628 case ObjectLiteral::Property::CONSTANT: 1604 case ObjectLiteral::Property::CONSTANT:
1629 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1605 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1630 case ObjectLiteral::Property::COMPUTED: 1606 case ObjectLiteral::Property::COMPUTED:
1631 if (property->emit_store()) { 1607 if (property->emit_store()) {
1632 __ Push(Smi::FromInt(NONE)); 1608 PushOperand(Smi::FromInt(NONE));
1633 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1609 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1634 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1610 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1635 } else { 1611 } else {
1636 __ Drop(3); 1612 DropOperands(3);
1637 } 1613 }
1638 break; 1614 break;
1639 1615
1640 case ObjectLiteral::Property::PROTOTYPE: 1616 case ObjectLiteral::Property::PROTOTYPE:
1641 UNREACHABLE(); 1617 UNREACHABLE();
1642 break; 1618 break;
1643 1619
1644 case ObjectLiteral::Property::GETTER: 1620 case ObjectLiteral::Property::GETTER:
1645 __ Push(Smi::FromInt(NONE)); 1621 PushOperand(Smi::FromInt(NONE));
1646 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1622 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1647 break; 1623 break;
1648 1624
1649 case ObjectLiteral::Property::SETTER: 1625 case ObjectLiteral::Property::SETTER:
1650 __ Push(Smi::FromInt(NONE)); 1626 PushOperand(Smi::FromInt(NONE));
1651 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1627 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1652 break; 1628 break;
1653 } 1629 }
1654 } 1630 }
1655 } 1631 }
1656 1632
1657 if (expr->has_function()) { 1633 if (expr->has_function()) {
1658 DCHECK(result_saved); 1634 DCHECK(result_saved);
1659 __ ld(a0, MemOperand(sp)); 1635 __ ld(a0, MemOperand(sp));
1660 __ push(a0); 1636 __ push(a0);
1661 __ CallRuntime(Runtime::kToFastProperties); 1637 __ CallRuntime(Runtime::kToFastProperties);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 int array_index = 0; 1682 int array_index = 0;
1707 for (; array_index < length; array_index++) { 1683 for (; array_index < length; array_index++) {
1708 Expression* subexpr = subexprs->at(array_index); 1684 Expression* subexpr = subexprs->at(array_index);
1709 DCHECK(!subexpr->IsSpread()); 1685 DCHECK(!subexpr->IsSpread());
1710 1686
1711 // If the subexpression is a literal or a simple materialized literal it 1687 // If the subexpression is a literal or a simple materialized literal it
1712 // is already set in the cloned array. 1688 // is already set in the cloned array.
1713 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1689 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1714 1690
1715 if (!result_saved) { 1691 if (!result_saved) {
1716 __ push(v0); // array literal 1692 PushOperand(v0); // array literal
1717 result_saved = true; 1693 result_saved = true;
1718 } 1694 }
1719 1695
1720 VisitForAccumulatorValue(subexpr); 1696 VisitForAccumulatorValue(subexpr);
1721 1697
1722 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); 1698 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index)));
1723 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1699 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1724 __ mov(StoreDescriptor::ValueRegister(), result_register()); 1700 __ mov(StoreDescriptor::ValueRegister(), result_register());
1725 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1701 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1726 Handle<Code> ic = 1702 Handle<Code> ic =
1727 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1703 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1728 CallIC(ic); 1704 CallIC(ic);
1729 1705
1730 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1706 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1731 } 1707 }
1732 1708
1733 // In case the array literal contains spread expressions it has two parts. The 1709 // In case the array literal contains spread expressions it has two parts. The
1734 // first part is the "static" array which has a literal index is handled 1710 // first part is the "static" array which has a literal index is handled
1735 // above. The second part is the part after the first spread expression 1711 // above. The second part is the part after the first spread expression
1736 // (inclusive) and these elements gets appended to the array. Note that the 1712 // (inclusive) and these elements gets appended to the array. Note that the
1737 // number elements an iterable produces is unknown ahead of time. 1713 // number elements an iterable produces is unknown ahead of time.
1738 if (array_index < length && result_saved) { 1714 if (array_index < length && result_saved) {
1739 __ Pop(v0); 1715 PopOperand(v0);
1740 result_saved = false; 1716 result_saved = false;
1741 } 1717 }
1742 for (; array_index < length; array_index++) { 1718 for (; array_index < length; array_index++) {
1743 Expression* subexpr = subexprs->at(array_index); 1719 Expression* subexpr = subexprs->at(array_index);
1744 1720
1745 __ Push(v0); 1721 PushOperand(v0);
1746 DCHECK(!subexpr->IsSpread()); 1722 DCHECK(!subexpr->IsSpread());
1747 VisitForStackValue(subexpr); 1723 VisitForStackValue(subexpr);
1748 __ CallRuntime(Runtime::kAppendElement); 1724 CallRuntimeWithOperands(Runtime::kAppendElement);
1749 1725
1750 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1726 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1751 } 1727 }
1752 1728
1753 if (result_saved) { 1729 if (result_saved) {
1754 context()->PlugTOS(); 1730 context()->PlugTOS();
1755 } else { 1731 } else {
1756 context()->Plug(v0); 1732 context()->Plug(v0);
1757 } 1733 }
1758 } 1734 }
(...skipping 20 matching lines...) Expand all
1779 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1755 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1780 } else { 1756 } else {
1781 VisitForStackValue(property->obj()); 1757 VisitForStackValue(property->obj());
1782 } 1758 }
1783 break; 1759 break;
1784 case NAMED_SUPER_PROPERTY: 1760 case NAMED_SUPER_PROPERTY:
1785 VisitForStackValue( 1761 VisitForStackValue(
1786 property->obj()->AsSuperPropertyReference()->this_var()); 1762 property->obj()->AsSuperPropertyReference()->this_var());
1787 VisitForAccumulatorValue( 1763 VisitForAccumulatorValue(
1788 property->obj()->AsSuperPropertyReference()->home_object()); 1764 property->obj()->AsSuperPropertyReference()->home_object());
1789 __ Push(result_register()); 1765 PushOperand(result_register());
1790 if (expr->is_compound()) { 1766 if (expr->is_compound()) {
1791 const Register scratch = a1; 1767 const Register scratch = a1;
1792 __ ld(scratch, MemOperand(sp, kPointerSize)); 1768 __ ld(scratch, MemOperand(sp, kPointerSize));
1793 __ Push(scratch, result_register()); 1769 PushOperands(scratch, result_register());
1794 } 1770 }
1795 break; 1771 break;
1796 case KEYED_SUPER_PROPERTY: { 1772 case KEYED_SUPER_PROPERTY: {
1797 const Register scratch = a1; 1773 const Register scratch = a1;
1798 VisitForStackValue( 1774 VisitForStackValue(
1799 property->obj()->AsSuperPropertyReference()->this_var()); 1775 property->obj()->AsSuperPropertyReference()->this_var());
1800 VisitForAccumulatorValue( 1776 VisitForAccumulatorValue(
1801 property->obj()->AsSuperPropertyReference()->home_object()); 1777 property->obj()->AsSuperPropertyReference()->home_object());
1802 __ Move(scratch, result_register()); 1778 __ Move(scratch, result_register());
1803 VisitForAccumulatorValue(property->key()); 1779 VisitForAccumulatorValue(property->key());
1804 __ Push(scratch, result_register()); 1780 PushOperands(scratch, result_register());
1805 if (expr->is_compound()) { 1781 if (expr->is_compound()) {
1806 const Register scratch1 = a4; 1782 const Register scratch1 = a4;
1807 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize)); 1783 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize));
1808 __ Push(scratch1, scratch, result_register()); 1784 PushOperands(scratch1, scratch, result_register());
1809 } 1785 }
1810 break; 1786 break;
1811 } 1787 }
1812 case KEYED_PROPERTY: 1788 case KEYED_PROPERTY:
1813 // We need the key and receiver on both the stack and in v0 and a1. 1789 // We need the key and receiver on both the stack and in v0 and a1.
1814 if (expr->is_compound()) { 1790 if (expr->is_compound()) {
1815 VisitForStackValue(property->obj()); 1791 VisitForStackValue(property->obj());
1816 VisitForStackValue(property->key()); 1792 VisitForStackValue(property->key());
1817 __ ld(LoadDescriptor::ReceiverRegister(), 1793 __ ld(LoadDescriptor::ReceiverRegister(),
1818 MemOperand(sp, 1 * kPointerSize)); 1794 MemOperand(sp, 1 * kPointerSize));
(...skipping 27 matching lines...) Expand all
1846 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1822 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1847 break; 1823 break;
1848 case KEYED_PROPERTY: 1824 case KEYED_PROPERTY:
1849 EmitKeyedPropertyLoad(property); 1825 EmitKeyedPropertyLoad(property);
1850 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1826 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1851 break; 1827 break;
1852 } 1828 }
1853 } 1829 }
1854 1830
1855 Token::Value op = expr->binary_op(); 1831 Token::Value op = expr->binary_op();
1856 __ push(v0); // Left operand goes on the stack. 1832 PushOperand(v0); // Left operand goes on the stack.
1857 VisitForAccumulatorValue(expr->value()); 1833 VisitForAccumulatorValue(expr->value());
1858 1834
1859 AccumulatorValueContext context(this); 1835 AccumulatorValueContext context(this);
1860 if (ShouldInlineSmiCase(op)) { 1836 if (ShouldInlineSmiCase(op)) {
1861 EmitInlineSmiBinaryOp(expr->binary_operation(), 1837 EmitInlineSmiBinaryOp(expr->binary_operation(),
1862 op, 1838 op,
1863 expr->target(), 1839 expr->target(),
1864 expr->value()); 1840 expr->value());
1865 } else { 1841 } else {
1866 EmitBinaryOp(expr->binary_operation(), op); 1842 EmitBinaryOp(expr->binary_operation(), op);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 __ sd(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); 1914 __ sd(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
1939 __ mov(a1, cp); 1915 __ mov(a1, cp);
1940 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, 1916 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2,
1941 kRAHasBeenSaved, kDontSaveFPRegs); 1917 kRAHasBeenSaved, kDontSaveFPRegs);
1942 __ Daddu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1918 __ Daddu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1943 __ Branch(&post_runtime, eq, sp, Operand(a1)); 1919 __ Branch(&post_runtime, eq, sp, Operand(a1));
1944 __ push(v0); // generator object 1920 __ push(v0); // generator object
1945 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1921 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1946 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1922 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1947 __ bind(&post_runtime); 1923 __ bind(&post_runtime);
1948 __ pop(result_register()); 1924 PopOperand(result_register());
1949 EmitReturnSequence(); 1925 EmitReturnSequence();
1950 1926
1951 __ bind(&resume); 1927 __ bind(&resume);
1952 context()->Plug(result_register()); 1928 context()->Plug(result_register());
1953 break; 1929 break;
1954 } 1930 }
1955 1931
1956 case Yield::kFinal: { 1932 case Yield::kFinal: {
1957 // Pop value from top-of-stack slot, box result into result register. 1933 // Pop value from top-of-stack slot, box result into result register.
1934 OperandStackDepthDecrement(1);
1958 EmitCreateIteratorResult(true); 1935 EmitCreateIteratorResult(true);
1959 EmitUnwindAndReturn(); 1936 EmitUnwindAndReturn();
1960 break; 1937 break;
1961 } 1938 }
1962 1939
1963 case Yield::kDelegating: 1940 case Yield::kDelegating:
1964 UNREACHABLE(); 1941 UNREACHABLE();
1965 } 1942 }
1966 } 1943 }
1967 1944
1968 1945
1969 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 1946 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1970 Expression *value, 1947 Expression *value,
1971 JSGeneratorObject::ResumeMode resume_mode) { 1948 JSGeneratorObject::ResumeMode resume_mode) {
1972 // The value stays in a0, and is ultimately read by the resumed generator, as 1949 // The value stays in a0, and is ultimately read by the resumed generator, as
1973 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1950 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1974 // is read to throw the value when the resumed generator is already closed. 1951 // is read to throw the value when the resumed generator is already closed.
1975 // a1 will hold the generator object until the activation has been resumed. 1952 // a1 will hold the generator object until the activation has been resumed.
1976 VisitForStackValue(generator); 1953 VisitForStackValue(generator);
1977 VisitForAccumulatorValue(value); 1954 VisitForAccumulatorValue(value);
1978 __ pop(a1); 1955 PopOperand(a1);
1979 1956
1980 // Store input value into generator object. 1957 // Store input value into generator object.
1981 __ sd(result_register(), 1958 __ sd(result_register(),
1982 FieldMemOperand(a1, JSGeneratorObject::kInputOffset)); 1959 FieldMemOperand(a1, JSGeneratorObject::kInputOffset));
1983 __ mov(a2, result_register()); 1960 __ mov(a2, result_register());
1984 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3, 1961 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3,
1985 kRAHasBeenSaved, kDontSaveFPRegs); 1962 kRAHasBeenSaved, kDontSaveFPRegs);
1986 1963
1987 // Load suspended function and context. 1964 // Load suspended function and context.
1988 __ ld(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset)); 1965 __ ld(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2056 __ Push(a1, result_register()); 2033 __ Push(a1, result_register());
2057 __ Push(Smi::FromInt(resume_mode)); 2034 __ Push(Smi::FromInt(resume_mode));
2058 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 2035 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
2059 // Not reached: the runtime call returns elsewhere. 2036 // Not reached: the runtime call returns elsewhere.
2060 __ stop("not-reached"); 2037 __ stop("not-reached");
2061 2038
2062 __ bind(&done); 2039 __ bind(&done);
2063 context()->Plug(result_register()); 2040 context()->Plug(result_register());
2064 } 2041 }
2065 2042
2043 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
2044 OperandStackDepthIncrement(2);
2045 __ Push(reg1, reg2);
2046 }
2047
2048 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
2049 Register reg3) {
2050 OperandStackDepthIncrement(3);
2051 __ Push(reg1, reg2, reg3);
2052 }
2053
2054 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
2055 Register reg3, Register reg4) {
2056 OperandStackDepthIncrement(4);
2057 __ Push(reg1, reg2, reg3, reg4);
2058 }
2059
2060 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) {
2061 OperandStackDepthDecrement(2);
2062 __ Pop(reg1, reg2);
2063 }
2064
2065 void FullCodeGenerator::EmitOperandStackDepthCheck() {
2066 if (FLAG_debug_code) {
2067 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
2068 operand_stack_depth_ * kPointerSize;
2069 __ Dsubu(v0, fp, sp);
2070 __ Assert(eq, kUnexpectedStackDepth, v0, Operand(expected_diff));
2071 }
2072 }
2066 2073
2067 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2074 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2068 Label allocate, done_allocate; 2075 Label allocate, done_allocate;
2069 2076
2070 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); 2077 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
2071 __ jmp(&done_allocate); 2078 __ jmp(&done_allocate);
2072 2079
2073 __ bind(&allocate); 2080 __ bind(&allocate);
2074 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2081 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2075 __ CallRuntime(Runtime::kAllocateInNewSpace); 2082 __ CallRuntime(Runtime::kAllocateInNewSpace);
(...skipping 18 matching lines...) Expand all
2094 Literal* key = prop->key()->AsLiteral(); 2101 Literal* key = prop->key()->AsLiteral();
2095 DCHECK(!prop->IsSuperAccess()); 2102 DCHECK(!prop->IsSuperAccess());
2096 2103
2097 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); 2104 __ li(LoadDescriptor::NameRegister(), Operand(key->value()));
2098 __ li(LoadDescriptor::SlotRegister(), 2105 __ li(LoadDescriptor::SlotRegister(),
2099 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2106 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2100 CallLoadIC(NOT_INSIDE_TYPEOF); 2107 CallLoadIC(NOT_INSIDE_TYPEOF);
2101 } 2108 }
2102 2109
2103 2110
2104 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2105 // Stack: receiver, home_object.
2106 SetExpressionPosition(prop);
2107
2108 Literal* key = prop->key()->AsLiteral();
2109 DCHECK(!key->value()->IsSmi());
2110 DCHECK(prop->IsSuperAccess());
2111
2112 __ Push(key->value());
2113 __ CallRuntime(Runtime::kLoadFromSuper);
2114 }
2115
2116
2117 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2118 // Call keyed load IC. It has register arguments receiver and key.
2119 SetExpressionPosition(prop);
2120
2121 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2122 __ li(LoadDescriptor::SlotRegister(),
2123 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2124 CallIC(ic);
2125 }
2126
2127
2128 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2129 // Stack: receiver, home_object, key.
2130 SetExpressionPosition(prop);
2131 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2132 }
2133
2134
2135 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2111 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2136 Token::Value op, 2112 Token::Value op,
2137 Expression* left_expr, 2113 Expression* left_expr,
2138 Expression* right_expr) { 2114 Expression* right_expr) {
2139 Label done, smi_case, stub_call; 2115 Label done, smi_case, stub_call;
2140 2116
2141 Register scratch1 = a2; 2117 Register scratch1 = a2;
2142 Register scratch2 = a3; 2118 Register scratch2 = a3;
2143 2119
2144 // Get the arguments. 2120 // Get the arguments.
2145 Register left = a1; 2121 Register left = a1;
2146 Register right = a0; 2122 Register right = a0;
2147 __ pop(left); 2123 PopOperand(left);
2148 __ mov(a0, result_register()); 2124 __ mov(a0, result_register());
2149 2125
2150 // Perform combined smi check on both operands. 2126 // Perform combined smi check on both operands.
2151 __ Or(scratch1, left, Operand(right)); 2127 __ Or(scratch1, left, Operand(right));
2152 STATIC_ASSERT(kSmiTag == 0); 2128 STATIC_ASSERT(kSmiTag == 0);
2153 JumpPatchSite patch_site(masm_); 2129 JumpPatchSite patch_site(masm_);
2154 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2130 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2155 2131
2156 __ bind(&stub_call); 2132 __ bind(&stub_call);
2157 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2133 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2227 for (int i = 0; i < lit->properties()->length(); i++) { 2203 for (int i = 0; i < lit->properties()->length(); i++) {
2228 ObjectLiteral::Property* property = lit->properties()->at(i); 2204 ObjectLiteral::Property* property = lit->properties()->at(i);
2229 Expression* value = property->value(); 2205 Expression* value = property->value();
2230 2206
2231 Register scratch = a1; 2207 Register scratch = a1;
2232 if (property->is_static()) { 2208 if (property->is_static()) {
2233 __ ld(scratch, MemOperand(sp, kPointerSize)); // constructor 2209 __ ld(scratch, MemOperand(sp, kPointerSize)); // constructor
2234 } else { 2210 } else {
2235 __ ld(scratch, MemOperand(sp, 0)); // prototype 2211 __ ld(scratch, MemOperand(sp, 0)); // prototype
2236 } 2212 }
2237 __ push(scratch); 2213 PushOperand(scratch);
2238 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2214 EmitPropertyKey(property, lit->GetIdForProperty(i));
2239 2215
2240 // The static prototype property is read only. We handle the non computed 2216 // The static prototype property is read only. We handle the non computed
2241 // property name case in the parser. Since this is the only case where we 2217 // property name case in the parser. Since this is the only case where we
2242 // need to check for an own read only property we special case this so we do 2218 // need to check for an own read only property we special case this so we do
2243 // not need to do this for every property. 2219 // not need to do this for every property.
2244 if (property->is_static() && property->is_computed_name()) { 2220 if (property->is_static() && property->is_computed_name()) {
2245 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2221 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2246 __ push(v0); 2222 __ push(v0);
2247 } 2223 }
2248 2224
2249 VisitForStackValue(value); 2225 VisitForStackValue(value);
2250 if (NeedsHomeObject(value)) { 2226 if (NeedsHomeObject(value)) {
2251 EmitSetHomeObject(value, 2, property->GetSlot()); 2227 EmitSetHomeObject(value, 2, property->GetSlot());
2252 } 2228 }
2253 2229
2254 switch (property->kind()) { 2230 switch (property->kind()) {
2255 case ObjectLiteral::Property::CONSTANT: 2231 case ObjectLiteral::Property::CONSTANT:
2256 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2232 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2257 case ObjectLiteral::Property::PROTOTYPE: 2233 case ObjectLiteral::Property::PROTOTYPE:
2258 UNREACHABLE(); 2234 UNREACHABLE();
2259 case ObjectLiteral::Property::COMPUTED: 2235 case ObjectLiteral::Property::COMPUTED:
2260 __ Push(Smi::FromInt(DONT_ENUM)); 2236 PushOperand(Smi::FromInt(DONT_ENUM));
2261 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2237 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2262 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2238 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2263 break; 2239 break;
2264 2240
2265 case ObjectLiteral::Property::GETTER: 2241 case ObjectLiteral::Property::GETTER:
2266 __ Push(Smi::FromInt(DONT_ENUM)); 2242 PushOperand(Smi::FromInt(DONT_ENUM));
2267 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2243 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2268 break; 2244 break;
2269 2245
2270 case ObjectLiteral::Property::SETTER: 2246 case ObjectLiteral::Property::SETTER:
2271 __ Push(Smi::FromInt(DONT_ENUM)); 2247 PushOperand(Smi::FromInt(DONT_ENUM));
2272 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2248 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2273 break; 2249 break;
2274 2250
2275 default: 2251 default:
2276 UNREACHABLE(); 2252 UNREACHABLE();
2277 } 2253 }
2278 } 2254 }
2279 } 2255 }
2280 2256
2281 2257
2282 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2258 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2283 __ mov(a0, result_register()); 2259 __ mov(a0, result_register());
2284 __ pop(a1); 2260 PopOperand(a1);
2285 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2261 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2286 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2262 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2287 CallIC(code, expr->BinaryOperationFeedbackId()); 2263 CallIC(code, expr->BinaryOperationFeedbackId());
2288 patch_site.EmitPatchInfo(); 2264 patch_site.EmitPatchInfo();
2289 context()->Plug(v0); 2265 context()->Plug(v0);
2290 } 2266 }
2291 2267
2292 2268
2293 void FullCodeGenerator::EmitAssignment(Expression* expr, 2269 void FullCodeGenerator::EmitAssignment(Expression* expr,
2294 FeedbackVectorSlot slot) { 2270 FeedbackVectorSlot slot) {
2295 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2271 DCHECK(expr->IsValidReferenceExpressionOrThis());
2296 2272
2297 Property* prop = expr->AsProperty(); 2273 Property* prop = expr->AsProperty();
2298 LhsKind assign_type = Property::GetAssignType(prop); 2274 LhsKind assign_type = Property::GetAssignType(prop);
2299 2275
2300 switch (assign_type) { 2276 switch (assign_type) {
2301 case VARIABLE: { 2277 case VARIABLE: {
2302 Variable* var = expr->AsVariableProxy()->var(); 2278 Variable* var = expr->AsVariableProxy()->var();
2303 EffectContext context(this); 2279 EffectContext context(this);
2304 EmitVariableAssignment(var, Token::ASSIGN, slot); 2280 EmitVariableAssignment(var, Token::ASSIGN, slot);
2305 break; 2281 break;
2306 } 2282 }
2307 case NAMED_PROPERTY: { 2283 case NAMED_PROPERTY: {
2308 __ push(result_register()); // Preserve value. 2284 PushOperand(result_register()); // Preserve value.
2309 VisitForAccumulatorValue(prop->obj()); 2285 VisitForAccumulatorValue(prop->obj());
2310 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); 2286 __ mov(StoreDescriptor::ReceiverRegister(), result_register());
2311 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2287 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2312 __ li(StoreDescriptor::NameRegister(), 2288 __ li(StoreDescriptor::NameRegister(),
2313 Operand(prop->key()->AsLiteral()->value())); 2289 Operand(prop->key()->AsLiteral()->value()));
2314 EmitLoadStoreICSlot(slot); 2290 EmitLoadStoreICSlot(slot);
2315 CallStoreIC(); 2291 CallStoreIC();
2316 break; 2292 break;
2317 } 2293 }
2318 case NAMED_SUPER_PROPERTY: { 2294 case NAMED_SUPER_PROPERTY: {
2319 __ Push(v0); 2295 PushOperand(v0);
2320 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2296 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2321 VisitForAccumulatorValue( 2297 VisitForAccumulatorValue(
2322 prop->obj()->AsSuperPropertyReference()->home_object()); 2298 prop->obj()->AsSuperPropertyReference()->home_object());
2323 // stack: value, this; v0: home_object 2299 // stack: value, this; v0: home_object
2324 Register scratch = a2; 2300 Register scratch = a2;
2325 Register scratch2 = a3; 2301 Register scratch2 = a3;
2326 __ mov(scratch, result_register()); // home_object 2302 __ mov(scratch, result_register()); // home_object
2327 __ ld(v0, MemOperand(sp, kPointerSize)); // value 2303 __ ld(v0, MemOperand(sp, kPointerSize)); // value
2328 __ ld(scratch2, MemOperand(sp, 0)); // this 2304 __ ld(scratch2, MemOperand(sp, 0)); // this
2329 __ sd(scratch2, MemOperand(sp, kPointerSize)); // this 2305 __ sd(scratch2, MemOperand(sp, kPointerSize)); // this
2330 __ sd(scratch, MemOperand(sp, 0)); // home_object 2306 __ sd(scratch, MemOperand(sp, 0)); // home_object
2331 // stack: this, home_object; v0: value 2307 // stack: this, home_object; v0: value
2332 EmitNamedSuperPropertyStore(prop); 2308 EmitNamedSuperPropertyStore(prop);
2333 break; 2309 break;
2334 } 2310 }
2335 case KEYED_SUPER_PROPERTY: { 2311 case KEYED_SUPER_PROPERTY: {
2336 __ Push(v0); 2312 PushOperand(v0);
2337 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2313 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2338 VisitForStackValue( 2314 VisitForStackValue(
2339 prop->obj()->AsSuperPropertyReference()->home_object()); 2315 prop->obj()->AsSuperPropertyReference()->home_object());
2340 VisitForAccumulatorValue(prop->key()); 2316 VisitForAccumulatorValue(prop->key());
2341 Register scratch = a2; 2317 Register scratch = a2;
2342 Register scratch2 = a3; 2318 Register scratch2 = a3;
2343 __ ld(scratch2, MemOperand(sp, 2 * kPointerSize)); // value 2319 __ ld(scratch2, MemOperand(sp, 2 * kPointerSize)); // value
2344 // stack: value, this, home_object; v0: key, a3: value 2320 // stack: value, this, home_object; v0: key, a3: value
2345 __ ld(scratch, MemOperand(sp, kPointerSize)); // this 2321 __ ld(scratch, MemOperand(sp, kPointerSize)); // this
2346 __ sd(scratch, MemOperand(sp, 2 * kPointerSize)); 2322 __ sd(scratch, MemOperand(sp, 2 * kPointerSize));
2347 __ ld(scratch, MemOperand(sp, 0)); // home_object 2323 __ ld(scratch, MemOperand(sp, 0)); // home_object
2348 __ sd(scratch, MemOperand(sp, kPointerSize)); 2324 __ sd(scratch, MemOperand(sp, kPointerSize));
2349 __ sd(v0, MemOperand(sp, 0)); 2325 __ sd(v0, MemOperand(sp, 0));
2350 __ Move(v0, scratch2); 2326 __ Move(v0, scratch2);
2351 // stack: this, home_object, key; v0: value. 2327 // stack: this, home_object, key; v0: value.
2352 EmitKeyedSuperPropertyStore(prop); 2328 EmitKeyedSuperPropertyStore(prop);
2353 break; 2329 break;
2354 } 2330 }
2355 case KEYED_PROPERTY: { 2331 case KEYED_PROPERTY: {
2356 __ push(result_register()); // Preserve value. 2332 PushOperand(result_register()); // Preserve value.
2357 VisitForStackValue(prop->obj()); 2333 VisitForStackValue(prop->obj());
2358 VisitForAccumulatorValue(prop->key()); 2334 VisitForAccumulatorValue(prop->key());
2359 __ Move(StoreDescriptor::NameRegister(), result_register()); 2335 __ Move(StoreDescriptor::NameRegister(), result_register());
2360 __ Pop(StoreDescriptor::ValueRegister(), 2336 PopOperands(StoreDescriptor::ValueRegister(),
2361 StoreDescriptor::ReceiverRegister()); 2337 StoreDescriptor::ReceiverRegister());
2362 EmitLoadStoreICSlot(slot); 2338 EmitLoadStoreICSlot(slot);
2363 Handle<Code> ic = 2339 Handle<Code> ic =
2364 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2340 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2365 CallIC(ic); 2341 CallIC(ic);
2366 break; 2342 break;
2367 } 2343 }
2368 } 2344 }
2369 context()->Plug(v0); 2345 context()->Plug(v0);
2370 } 2346 }
2371 2347
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 2466
2491 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2467 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2492 // Assignment to a property, using a named store IC. 2468 // Assignment to a property, using a named store IC.
2493 Property* prop = expr->target()->AsProperty(); 2469 Property* prop = expr->target()->AsProperty();
2494 DCHECK(prop != NULL); 2470 DCHECK(prop != NULL);
2495 DCHECK(prop->key()->IsLiteral()); 2471 DCHECK(prop->key()->IsLiteral());
2496 2472
2497 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2473 __ mov(StoreDescriptor::ValueRegister(), result_register());
2498 __ li(StoreDescriptor::NameRegister(), 2474 __ li(StoreDescriptor::NameRegister(),
2499 Operand(prop->key()->AsLiteral()->value())); 2475 Operand(prop->key()->AsLiteral()->value()));
2500 __ pop(StoreDescriptor::ReceiverRegister()); 2476 PopOperand(StoreDescriptor::ReceiverRegister());
2501 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2477 EmitLoadStoreICSlot(expr->AssignmentSlot());
2502 CallStoreIC(); 2478 CallStoreIC();
2503 2479
2504 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2480 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2505 context()->Plug(v0); 2481 context()->Plug(v0);
2506 } 2482 }
2507 2483
2508 2484
2509 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2485 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2510 // Assignment to named property of super. 2486 // Assignment to named property of super.
2511 // v0 : value 2487 // v0 : value
2512 // stack : receiver ('this'), home_object 2488 // stack : receiver ('this'), home_object
2513 DCHECK(prop != NULL); 2489 DCHECK(prop != NULL);
2514 Literal* key = prop->key()->AsLiteral(); 2490 Literal* key = prop->key()->AsLiteral();
2515 DCHECK(key != NULL); 2491 DCHECK(key != NULL);
2516 2492
2517 __ Push(key->value()); 2493 PushOperand(key->value());
2518 __ Push(v0); 2494 PushOperand(v0);
2519 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2495 CallRuntimeWithOperands(is_strict(language_mode())
2520 : Runtime::kStoreToSuper_Sloppy)); 2496 ? Runtime::kStoreToSuper_Strict
2497 : Runtime::kStoreToSuper_Sloppy);
2521 } 2498 }
2522 2499
2523 2500
2524 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2501 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2525 // Assignment to named property of super. 2502 // Assignment to named property of super.
2526 // v0 : value 2503 // v0 : value
2527 // stack : receiver ('this'), home_object, key 2504 // stack : receiver ('this'), home_object, key
2528 DCHECK(prop != NULL); 2505 DCHECK(prop != NULL);
2529 2506
2530 __ Push(v0); 2507 PushOperand(v0);
2531 __ CallRuntime((is_strict(language_mode()) 2508 CallRuntimeWithOperands(is_strict(language_mode())
2532 ? Runtime::kStoreKeyedToSuper_Strict 2509 ? Runtime::kStoreKeyedToSuper_Strict
2533 : Runtime::kStoreKeyedToSuper_Sloppy)); 2510 : Runtime::kStoreKeyedToSuper_Sloppy);
2534 } 2511 }
2535 2512
2536 2513
2537 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2514 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2538 // Assignment to a property, using a keyed store IC. 2515 // Assignment to a property, using a keyed store IC.
2539 // Call keyed store IC. 2516 // Call keyed store IC.
2540 // The arguments are: 2517 // The arguments are:
2541 // - a0 is the value, 2518 // - a0 is the value,
2542 // - a1 is the key, 2519 // - a1 is the key,
2543 // - a2 is the receiver. 2520 // - a2 is the receiver.
2544 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2521 __ mov(StoreDescriptor::ValueRegister(), result_register());
2545 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2522 PopOperands(StoreDescriptor::ReceiverRegister(),
2523 StoreDescriptor::NameRegister());
2546 DCHECK(StoreDescriptor::ValueRegister().is(a0)); 2524 DCHECK(StoreDescriptor::ValueRegister().is(a0));
2547 2525
2548 Handle<Code> ic = 2526 Handle<Code> ic =
2549 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2527 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2550 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2528 EmitLoadStoreICSlot(expr->AssignmentSlot());
2551 CallIC(ic); 2529 CallIC(ic);
2552 2530
2553 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2531 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2554 context()->Plug(v0); 2532 context()->Plug(v0);
2555 } 2533 }
(...skipping 14 matching lines...) Expand all
2570 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2548 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2571 VisitForStackValue( 2549 VisitForStackValue(
2572 expr->obj()->AsSuperPropertyReference()->home_object()); 2550 expr->obj()->AsSuperPropertyReference()->home_object());
2573 EmitNamedSuperPropertyLoad(expr); 2551 EmitNamedSuperPropertyLoad(expr);
2574 } 2552 }
2575 } else { 2553 } else {
2576 if (!expr->IsSuperAccess()) { 2554 if (!expr->IsSuperAccess()) {
2577 VisitForStackValue(expr->obj()); 2555 VisitForStackValue(expr->obj());
2578 VisitForAccumulatorValue(expr->key()); 2556 VisitForAccumulatorValue(expr->key());
2579 __ Move(LoadDescriptor::NameRegister(), v0); 2557 __ Move(LoadDescriptor::NameRegister(), v0);
2580 __ pop(LoadDescriptor::ReceiverRegister()); 2558 PopOperand(LoadDescriptor::ReceiverRegister());
2581 EmitKeyedPropertyLoad(expr); 2559 EmitKeyedPropertyLoad(expr);
2582 } else { 2560 } else {
2583 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2561 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2584 VisitForStackValue( 2562 VisitForStackValue(
2585 expr->obj()->AsSuperPropertyReference()->home_object()); 2563 expr->obj()->AsSuperPropertyReference()->home_object());
2586 VisitForStackValue(expr->key()); 2564 VisitForStackValue(expr->key());
2587 EmitKeyedSuperPropertyLoad(expr); 2565 EmitKeyedSuperPropertyLoad(expr);
2588 } 2566 }
2589 } 2567 }
2590 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2568 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
(...skipping 15 matching lines...) Expand all
2606 // Get the target function. 2584 // Get the target function.
2607 ConvertReceiverMode convert_mode; 2585 ConvertReceiverMode convert_mode;
2608 if (callee->IsVariableProxy()) { 2586 if (callee->IsVariableProxy()) {
2609 { StackValueContext context(this); 2587 { StackValueContext context(this);
2610 EmitVariableLoad(callee->AsVariableProxy()); 2588 EmitVariableLoad(callee->AsVariableProxy());
2611 PrepareForBailout(callee, NO_REGISTERS); 2589 PrepareForBailout(callee, NO_REGISTERS);
2612 } 2590 }
2613 // Push undefined as receiver. This is patched in the method prologue if it 2591 // Push undefined as receiver. This is patched in the method prologue if it
2614 // is a sloppy mode method. 2592 // is a sloppy mode method.
2615 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 2593 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2616 __ push(at); 2594 PushOperand(at);
2617 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2595 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2618 } else { 2596 } else {
2619 // Load the function from the receiver. 2597 // Load the function from the receiver.
2620 DCHECK(callee->IsProperty()); 2598 DCHECK(callee->IsProperty());
2621 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2599 DCHECK(!callee->AsProperty()->IsSuperAccess());
2622 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2600 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2623 EmitNamedPropertyLoad(callee->AsProperty()); 2601 EmitNamedPropertyLoad(callee->AsProperty());
2624 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2602 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2625 // Push the target function under the receiver. 2603 // Push the target function under the receiver.
2626 __ ld(at, MemOperand(sp, 0)); 2604 __ ld(at, MemOperand(sp, 0));
2627 __ push(at); 2605 PushOperand(at);
2628 __ sd(v0, MemOperand(sp, kPointerSize)); 2606 __ sd(v0, MemOperand(sp, kPointerSize));
2629 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2607 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2630 } 2608 }
2631 2609
2632 EmitCall(expr, convert_mode); 2610 EmitCall(expr, convert_mode);
2633 } 2611 }
2634 2612
2635 2613
2636 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2614 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2637 SetExpressionPosition(expr); 2615 SetExpressionPosition(expr);
2638 Expression* callee = expr->expression(); 2616 Expression* callee = expr->expression();
2639 DCHECK(callee->IsProperty()); 2617 DCHECK(callee->IsProperty());
2640 Property* prop = callee->AsProperty(); 2618 Property* prop = callee->AsProperty();
2641 DCHECK(prop->IsSuperAccess()); 2619 DCHECK(prop->IsSuperAccess());
2642 2620
2643 Literal* key = prop->key()->AsLiteral(); 2621 Literal* key = prop->key()->AsLiteral();
2644 DCHECK(!key->value()->IsSmi()); 2622 DCHECK(!key->value()->IsSmi());
2645 // Load the function from the receiver. 2623 // Load the function from the receiver.
2646 const Register scratch = a1; 2624 const Register scratch = a1;
2647 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2625 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2648 VisitForAccumulatorValue(super_ref->home_object()); 2626 VisitForAccumulatorValue(super_ref->home_object());
2649 __ mov(scratch, v0); 2627 __ mov(scratch, v0);
2650 VisitForAccumulatorValue(super_ref->this_var()); 2628 VisitForAccumulatorValue(super_ref->this_var());
2651 __ Push(scratch, v0, v0, scratch); 2629 PushOperands(scratch, v0, v0, scratch);
2652 __ Push(key->value()); 2630 PushOperand(key->value());
2653 2631
2654 // Stack here: 2632 // Stack here:
2655 // - home_object 2633 // - home_object
2656 // - this (receiver) 2634 // - this (receiver)
2657 // - this (receiver) <-- LoadFromSuper will pop here and below. 2635 // - this (receiver) <-- LoadFromSuper will pop here and below.
2658 // - home_object 2636 // - home_object
2659 // - key 2637 // - key
2660 __ CallRuntime(Runtime::kLoadFromSuper); 2638 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2661 2639
2662 // Replace home_object with target function. 2640 // Replace home_object with target function.
2663 __ sd(v0, MemOperand(sp, kPointerSize)); 2641 __ sd(v0, MemOperand(sp, kPointerSize));
2664 2642
2665 // Stack here: 2643 // Stack here:
2666 // - target function 2644 // - target function
2667 // - this (receiver) 2645 // - this (receiver)
2668 EmitCall(expr); 2646 EmitCall(expr);
2669 } 2647 }
2670 2648
2671 2649
2672 // Code common for calls using the IC. 2650 // Code common for calls using the IC.
2673 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2651 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2674 Expression* key) { 2652 Expression* key) {
2675 // Load the key. 2653 // Load the key.
2676 VisitForAccumulatorValue(key); 2654 VisitForAccumulatorValue(key);
2677 2655
2678 Expression* callee = expr->expression(); 2656 Expression* callee = expr->expression();
2679 2657
2680 // Load the function from the receiver. 2658 // Load the function from the receiver.
2681 DCHECK(callee->IsProperty()); 2659 DCHECK(callee->IsProperty());
2682 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2660 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2683 __ Move(LoadDescriptor::NameRegister(), v0); 2661 __ Move(LoadDescriptor::NameRegister(), v0);
2684 EmitKeyedPropertyLoad(callee->AsProperty()); 2662 EmitKeyedPropertyLoad(callee->AsProperty());
2685 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2663 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2686 2664
2687 // Push the target function under the receiver. 2665 // Push the target function under the receiver.
2688 __ ld(at, MemOperand(sp, 0)); 2666 __ ld(at, MemOperand(sp, 0));
2689 __ push(at); 2667 PushOperand(at);
2690 __ sd(v0, MemOperand(sp, kPointerSize)); 2668 __ sd(v0, MemOperand(sp, kPointerSize));
2691 2669
2692 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2670 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2693 } 2671 }
2694 2672
2695 2673
2696 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2674 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2697 Expression* callee = expr->expression(); 2675 Expression* callee = expr->expression();
2698 DCHECK(callee->IsProperty()); 2676 DCHECK(callee->IsProperty());
2699 Property* prop = callee->AsProperty(); 2677 Property* prop = callee->AsProperty();
2700 DCHECK(prop->IsSuperAccess()); 2678 DCHECK(prop->IsSuperAccess());
2701 2679
2702 SetExpressionPosition(prop); 2680 SetExpressionPosition(prop);
2703 // Load the function from the receiver. 2681 // Load the function from the receiver.
2704 const Register scratch = a1; 2682 const Register scratch = a1;
2705 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2683 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2706 VisitForAccumulatorValue(super_ref->home_object()); 2684 VisitForAccumulatorValue(super_ref->home_object());
2707 __ Move(scratch, v0); 2685 __ Move(scratch, v0);
2708 VisitForAccumulatorValue(super_ref->this_var()); 2686 VisitForAccumulatorValue(super_ref->this_var());
2709 __ Push(scratch, v0, v0, scratch); 2687 PushOperands(scratch, v0, v0, scratch);
2710 VisitForStackValue(prop->key()); 2688 VisitForStackValue(prop->key());
2711 2689
2712 // Stack here: 2690 // Stack here:
2713 // - home_object 2691 // - home_object
2714 // - this (receiver) 2692 // - this (receiver)
2715 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2693 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2716 // - home_object 2694 // - home_object
2717 // - key 2695 // - key
2718 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2696 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2719 2697
2720 // Replace home_object with target function. 2698 // Replace home_object with target function.
2721 __ sd(v0, MemOperand(sp, kPointerSize)); 2699 __ sd(v0, MemOperand(sp, kPointerSize));
2722 2700
2723 // Stack here: 2701 // Stack here:
2724 // - target function 2702 // - target function
2725 // - this (receiver) 2703 // - this (receiver)
2726 EmitCall(expr); 2704 EmitCall(expr);
2727 } 2705 }
2728 2706
(...skipping 18 matching lines...) Expand all
2747 EmitProfilingCounterHandlingForReturnSequence(true); 2725 EmitProfilingCounterHandlingForReturnSequence(true);
2748 } 2726 }
2749 Handle<Code> ic = 2727 Handle<Code> ic =
2750 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2728 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2751 .code(); 2729 .code();
2752 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); 2730 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
2753 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2731 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2754 // Don't assign a type feedback id to the IC, since type feedback is provided 2732 // Don't assign a type feedback id to the IC, since type feedback is provided
2755 // by the vector above. 2733 // by the vector above.
2756 CallIC(ic); 2734 CallIC(ic);
2735 OperandStackDepthDecrement(arg_count + 1);
2736
2757 RecordJSReturnSite(expr); 2737 RecordJSReturnSite(expr);
2758 // Restore context register. 2738 // Restore context register.
2759 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2739 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2760 context()->DropAndPlug(1, v0); 2740 context()->DropAndPlug(1, v0);
2761 } 2741 }
2762 2742
2763 2743
2764 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2744 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2765 // a6: copy of the first argument or undefined if it doesn't exist. 2745 // a6: copy of the first argument or undefined if it doesn't exist.
2766 if (arg_count > 0) { 2746 if (arg_count > 0) {
(...skipping 26 matching lines...) Expand all
2793 SetExpressionPosition(callee); 2773 SetExpressionPosition(callee);
2794 // Generate code for loading from variables potentially shadowed by 2774 // Generate code for loading from variables potentially shadowed by
2795 // eval-introduced variables. 2775 // eval-introduced variables.
2796 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2776 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2797 2777
2798 __ bind(&slow); 2778 __ bind(&slow);
2799 // Call the runtime to find the function to call (returned in v0) 2779 // Call the runtime to find the function to call (returned in v0)
2800 // and the object holding it (returned in v1). 2780 // and the object holding it (returned in v1).
2801 __ Push(callee->name()); 2781 __ Push(callee->name());
2802 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2782 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2803 __ Push(v0, v1); // Function, receiver. 2783 PushOperands(v0, v1); // Function, receiver.
2804 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2784 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2805 2785
2806 // If fast case code has been generated, emit code to push the 2786 // If fast case code has been generated, emit code to push the
2807 // function and receiver and have the slow path jump around this 2787 // function and receiver and have the slow path jump around this
2808 // code. 2788 // code.
2809 if (done.is_linked()) { 2789 if (done.is_linked()) {
2810 Label call; 2790 Label call;
2811 __ Branch(&call); 2791 __ Branch(&call);
2812 __ bind(&done); 2792 __ bind(&done);
2813 // Push function. 2793 // Push function.
2814 __ push(v0); 2794 __ push(v0);
2815 // The receiver is implicitly the global receiver. Indicate this 2795 // The receiver is implicitly the global receiver. Indicate this
2816 // by passing the hole to the call function stub. 2796 // by passing the hole to the call function stub.
2817 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); 2797 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
2818 __ push(a1); 2798 __ push(a1);
2819 __ bind(&call); 2799 __ bind(&call);
2820 } 2800 }
2821 } else { 2801 } else {
2822 VisitForStackValue(callee); 2802 VisitForStackValue(callee);
2823 // refEnv.WithBaseObject() 2803 // refEnv.WithBaseObject()
2824 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 2804 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
2825 __ push(a2); // Reserved receiver slot. 2805 PushOperand(a2); // Reserved receiver slot.
2826 } 2806 }
2827 } 2807 }
2828 2808
2829 2809
2830 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2810 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2831 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2811 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2832 // to resolve the function we need to call. Then we call the resolved 2812 // to resolve the function we need to call. Then we call the resolved
2833 // function using the given arguments. 2813 // function using the given arguments.
2834 ZoneList<Expression*>* args = expr->arguments(); 2814 ZoneList<Expression*>* args = expr->arguments();
2835 int arg_count = args->length(); 2815 int arg_count = args->length();
(...skipping 14 matching lines...) Expand all
2850 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2830 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2851 2831
2852 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2832 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2853 // Record source position for debugger. 2833 // Record source position for debugger.
2854 SetCallPosition(expr); 2834 SetCallPosition(expr);
2855 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2835 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2856 __ li(a0, Operand(arg_count)); 2836 __ li(a0, Operand(arg_count));
2857 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2837 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2858 expr->tail_call_mode()), 2838 expr->tail_call_mode()),
2859 RelocInfo::CODE_TARGET); 2839 RelocInfo::CODE_TARGET);
2840 OperandStackDepthDecrement(arg_count + 1);
2860 RecordJSReturnSite(expr); 2841 RecordJSReturnSite(expr);
2861 // Restore context register. 2842 // Restore context register.
2862 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2843 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2863 context()->DropAndPlug(1, v0); 2844 context()->DropAndPlug(1, v0);
2864 } 2845 }
2865 2846
2866 2847
2867 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2848 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2868 Comment cmnt(masm_, "[ CallNew"); 2849 Comment cmnt(masm_, "[ CallNew");
2869 // According to ECMA-262, section 11.2.2, page 44, the function 2850 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2890 // Load function and argument count into a1 and a0. 2871 // Load function and argument count into a1 and a0.
2891 __ li(a0, Operand(arg_count)); 2872 __ li(a0, Operand(arg_count));
2892 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); 2873 __ ld(a1, MemOperand(sp, arg_count * kPointerSize));
2893 2874
2894 // Record call targets in unoptimized code. 2875 // Record call targets in unoptimized code.
2895 __ EmitLoadTypeFeedbackVector(a2); 2876 __ EmitLoadTypeFeedbackVector(a2);
2896 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2877 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
2897 2878
2898 CallConstructStub stub(isolate()); 2879 CallConstructStub stub(isolate());
2899 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2880 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2881 OperandStackDepthDecrement(arg_count + 1);
2900 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2882 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2901 // Restore context register. 2883 // Restore context register.
2902 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2884 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2903 context()->Plug(v0); 2885 context()->Plug(v0);
2904 } 2886 }
2905 2887
2906 2888
2907 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2889 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2908 SuperCallReference* super_call_ref = 2890 SuperCallReference* super_call_ref =
2909 expr->expression()->AsSuperCallReference(); 2891 expr->expression()->AsSuperCallReference();
2910 DCHECK_NOT_NULL(super_call_ref); 2892 DCHECK_NOT_NULL(super_call_ref);
2911 2893
2912 // Push the super constructor target on the stack (may be null, 2894 // Push the super constructor target on the stack (may be null,
2913 // but the Construct builtin can deal with that properly). 2895 // but the Construct builtin can deal with that properly).
2914 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2896 VisitForAccumulatorValue(super_call_ref->this_function_var());
2915 __ AssertFunction(result_register()); 2897 __ AssertFunction(result_register());
2916 __ ld(result_register(), 2898 __ ld(result_register(),
2917 FieldMemOperand(result_register(), HeapObject::kMapOffset)); 2899 FieldMemOperand(result_register(), HeapObject::kMapOffset));
2918 __ ld(result_register(), 2900 __ ld(result_register(),
2919 FieldMemOperand(result_register(), Map::kPrototypeOffset)); 2901 FieldMemOperand(result_register(), Map::kPrototypeOffset));
2920 __ Push(result_register()); 2902 PushOperand(result_register());
2921 2903
2922 // Push the arguments ("left-to-right") on the stack. 2904 // Push the arguments ("left-to-right") on the stack.
2923 ZoneList<Expression*>* args = expr->arguments(); 2905 ZoneList<Expression*>* args = expr->arguments();
2924 int arg_count = args->length(); 2906 int arg_count = args->length();
2925 for (int i = 0; i < arg_count; i++) { 2907 for (int i = 0; i < arg_count; i++) {
2926 VisitForStackValue(args->at(i)); 2908 VisitForStackValue(args->at(i));
2927 } 2909 }
2928 2910
2929 // Call the construct call builtin that handles allocation and 2911 // Call the construct call builtin that handles allocation and
2930 // constructor invocation. 2912 // constructor invocation.
2931 SetConstructCallPosition(expr); 2913 SetConstructCallPosition(expr);
2932 2914
2933 // Load new target into a3. 2915 // Load new target into a3.
2934 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2916 VisitForAccumulatorValue(super_call_ref->new_target_var());
2935 __ mov(a3, result_register()); 2917 __ mov(a3, result_register());
2936 2918
2937 // Load function and argument count into a1 and a0. 2919 // Load function and argument count into a1 and a0.
2938 __ li(a0, Operand(arg_count)); 2920 __ li(a0, Operand(arg_count));
2939 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); 2921 __ ld(a1, MemOperand(sp, arg_count * kPointerSize));
2940 2922
2941 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2923 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2924 OperandStackDepthDecrement(arg_count + 1);
2942 2925
2943 RecordJSReturnSite(expr); 2926 RecordJSReturnSite(expr);
2944 2927
2945 // Restore context register. 2928 // Restore context register.
2946 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2929 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2947 context()->Plug(v0); 2930 context()->Plug(v0);
2948 } 2931 }
2949 2932
2950 2933
2951 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2934 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
3154 ZoneList<Expression*>* args = expr->arguments(); 3137 ZoneList<Expression*>* args = expr->arguments();
3155 DCHECK_EQ(3, args->length()); 3138 DCHECK_EQ(3, args->length());
3156 3139
3157 Register string = v0; 3140 Register string = v0;
3158 Register index = a1; 3141 Register index = a1;
3159 Register value = a2; 3142 Register value = a2;
3160 3143
3161 VisitForStackValue(args->at(0)); // index 3144 VisitForStackValue(args->at(0)); // index
3162 VisitForStackValue(args->at(1)); // value 3145 VisitForStackValue(args->at(1)); // value
3163 VisitForAccumulatorValue(args->at(2)); // string 3146 VisitForAccumulatorValue(args->at(2)); // string
3164 __ Pop(index, value); 3147 PopOperands(index, value);
3165 3148
3166 if (FLAG_debug_code) { 3149 if (FLAG_debug_code) {
3167 __ SmiTst(value, at); 3150 __ SmiTst(value, at);
3168 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); 3151 __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
3169 __ SmiTst(index, at); 3152 __ SmiTst(index, at);
3170 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); 3153 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
3171 __ SmiUntag(index, index); 3154 __ SmiUntag(index, index);
3172 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3155 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3173 Register scratch = t1; 3156 Register scratch = t1;
3174 __ EmitSeqStringSetCharCheck( 3157 __ EmitSeqStringSetCharCheck(
(...skipping 16 matching lines...) Expand all
3191 ZoneList<Expression*>* args = expr->arguments(); 3174 ZoneList<Expression*>* args = expr->arguments();
3192 DCHECK_EQ(3, args->length()); 3175 DCHECK_EQ(3, args->length());
3193 3176
3194 Register string = v0; 3177 Register string = v0;
3195 Register index = a1; 3178 Register index = a1;
3196 Register value = a2; 3179 Register value = a2;
3197 3180
3198 VisitForStackValue(args->at(0)); // index 3181 VisitForStackValue(args->at(0)); // index
3199 VisitForStackValue(args->at(1)); // value 3182 VisitForStackValue(args->at(1)); // value
3200 VisitForAccumulatorValue(args->at(2)); // string 3183 VisitForAccumulatorValue(args->at(2)); // string
3201 __ Pop(index, value); 3184 PopOperands(index, value);
3202 3185
3203 if (FLAG_debug_code) { 3186 if (FLAG_debug_code) {
3204 __ SmiTst(value, at); 3187 __ SmiTst(value, at);
3205 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); 3188 __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
3206 __ SmiTst(index, at); 3189 __ SmiTst(index, at);
3207 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); 3190 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
3208 __ SmiUntag(index, index); 3191 __ SmiUntag(index, index);
3209 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3192 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3210 Register scratch = t1; 3193 Register scratch = t1;
3211 __ EmitSeqStringSetCharCheck( 3194 __ EmitSeqStringSetCharCheck(
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 DCHECK(args->length() == 2); 3249 DCHECK(args->length() == 2);
3267 3250
3268 VisitForStackValue(args->at(0)); 3251 VisitForStackValue(args->at(0));
3269 VisitForAccumulatorValue(args->at(1)); 3252 VisitForAccumulatorValue(args->at(1));
3270 __ mov(a0, result_register()); 3253 __ mov(a0, result_register());
3271 3254
3272 Register object = a1; 3255 Register object = a1;
3273 Register index = a0; 3256 Register index = a0;
3274 Register result = v0; 3257 Register result = v0;
3275 3258
3276 __ pop(object); 3259 PopOperand(object);
3277 3260
3278 Label need_conversion; 3261 Label need_conversion;
3279 Label index_out_of_range; 3262 Label index_out_of_range;
3280 Label done; 3263 Label done;
3281 StringCharCodeAtGenerator generator(object, 3264 StringCharCodeAtGenerator generator(object,
3282 index, 3265 index,
3283 result, 3266 result,
3284 &need_conversion, 3267 &need_conversion,
3285 &need_conversion, 3268 &need_conversion,
3286 &index_out_of_range, 3269 &index_out_of_range,
(...skipping 27 matching lines...) Expand all
3314 3297
3315 VisitForStackValue(args->at(0)); 3298 VisitForStackValue(args->at(0));
3316 VisitForAccumulatorValue(args->at(1)); 3299 VisitForAccumulatorValue(args->at(1));
3317 __ mov(a0, result_register()); 3300 __ mov(a0, result_register());
3318 3301
3319 Register object = a1; 3302 Register object = a1;
3320 Register index = a0; 3303 Register index = a0;
3321 Register scratch = a3; 3304 Register scratch = a3;
3322 Register result = v0; 3305 Register result = v0;
3323 3306
3324 __ pop(object); 3307 PopOperand(object);
3325 3308
3326 Label need_conversion; 3309 Label need_conversion;
3327 Label index_out_of_range; 3310 Label index_out_of_range;
3328 Label done; 3311 Label done;
3329 StringCharAtGenerator generator(object, 3312 StringCharAtGenerator generator(object,
3330 index, 3313 index,
3331 scratch, 3314 scratch,
3332 result, 3315 result,
3333 &need_conversion, 3316 &need_conversion,
3334 &need_conversion, 3317 &need_conversion,
(...skipping 29 matching lines...) Expand all
3364 for (Expression* const arg : *args) { 3347 for (Expression* const arg : *args) {
3365 VisitForStackValue(arg); 3348 VisitForStackValue(arg);
3366 } 3349 }
3367 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3350 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3368 // Move target to a1. 3351 // Move target to a1.
3369 int const argc = args->length() - 2; 3352 int const argc = args->length() - 2;
3370 __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize)); 3353 __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize));
3371 // Call the target. 3354 // Call the target.
3372 __ li(a0, Operand(argc)); 3355 __ li(a0, Operand(argc));
3373 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3356 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3357 OperandStackDepthDecrement(argc + 1);
3374 // Restore context register. 3358 // Restore context register.
3375 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3359 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3376 // Discard the function left on TOS. 3360 // Discard the function left on TOS.
3377 context()->DropAndPlug(1, v0); 3361 context()->DropAndPlug(1, v0);
3378 } 3362 }
3379 3363
3380 3364
3381 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3365 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3382 ZoneList<Expression*>* args = expr->arguments(); 3366 ZoneList<Expression*>* args = expr->arguments();
3383 VisitForAccumulatorValue(args->at(0)); 3367 VisitForAccumulatorValue(args->at(0));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3449 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex); 3433 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex);
3450 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 3434 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
3451 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 3435 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset));
3452 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); 3436 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset));
3453 __ sd(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); 3437 __ sd(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset));
3454 __ sd(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); 3438 __ sd(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset));
3455 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3439 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3456 __ jmp(&done); 3440 __ jmp(&done);
3457 3441
3458 __ bind(&runtime); 3442 __ bind(&runtime);
3459 __ CallRuntime(Runtime::kCreateIterResultObject); 3443 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3460 3444
3461 __ bind(&done); 3445 __ bind(&done);
3462 context()->Plug(v0); 3446 context()->Plug(v0);
3463 } 3447 }
3464 3448
3465 3449
3466 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3450 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3467 // Push undefined as the receiver. 3451 // Push undefined as the receiver.
3468 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 3452 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
3469 __ push(v0); 3453 PushOperand(v0);
3470 3454
3471 __ LoadNativeContextSlot(expr->context_index(), v0); 3455 __ LoadNativeContextSlot(expr->context_index(), v0);
3472 } 3456 }
3473 3457
3474 3458
3475 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3459 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3476 ZoneList<Expression*>* args = expr->arguments(); 3460 ZoneList<Expression*>* args = expr->arguments();
3477 int arg_count = args->length(); 3461 int arg_count = args->length();
3478 3462
3479 SetCallPosition(expr); 3463 SetCallPosition(expr);
3480 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 3464 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
3481 __ li(a0, Operand(arg_count)); 3465 __ li(a0, Operand(arg_count));
3482 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3466 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3483 RelocInfo::CODE_TARGET); 3467 RelocInfo::CODE_TARGET);
3468 OperandStackDepthDecrement(arg_count + 1);
3484 } 3469 }
3485 3470
3486 3471
3487 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3472 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3488 ZoneList<Expression*>* args = expr->arguments(); 3473 ZoneList<Expression*>* args = expr->arguments();
3489 int arg_count = args->length(); 3474 int arg_count = args->length();
3490 3475
3491 if (expr->is_jsruntime()) { 3476 if (expr->is_jsruntime()) {
3492 Comment cmnt(masm_, "[ CallRuntime"); 3477 Comment cmnt(masm_, "[ CallRuntime");
3493 EmitLoadJSRuntimeFunction(expr); 3478 EmitLoadJSRuntimeFunction(expr);
3494 3479
3495 // Push the target function under the receiver. 3480 // Push the target function under the receiver.
3496 __ ld(at, MemOperand(sp, 0)); 3481 __ ld(at, MemOperand(sp, 0));
3497 __ push(at); 3482 PushOperand(at);
3498 __ sd(v0, MemOperand(sp, kPointerSize)); 3483 __ sd(v0, MemOperand(sp, kPointerSize));
3499 3484
3500 // Push the arguments ("left-to-right"). 3485 // Push the arguments ("left-to-right").
3501 for (int i = 0; i < arg_count; i++) { 3486 for (int i = 0; i < arg_count; i++) {
3502 VisitForStackValue(args->at(i)); 3487 VisitForStackValue(args->at(i));
3503 } 3488 }
3504 3489
3505 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3490 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3506 EmitCallJSRuntimeFunction(expr); 3491 EmitCallJSRuntimeFunction(expr);
3507 3492
(...skipping 14 matching lines...) Expand all
3522 default: { 3507 default: {
3523 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3508 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3524 // Push the arguments ("left-to-right"). 3509 // Push the arguments ("left-to-right").
3525 for (int i = 0; i < arg_count; i++) { 3510 for (int i = 0; i < arg_count; i++) {
3526 VisitForStackValue(args->at(i)); 3511 VisitForStackValue(args->at(i));
3527 } 3512 }
3528 3513
3529 // Call the C runtime function. 3514 // Call the C runtime function.
3530 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3515 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3531 __ CallRuntime(expr->function(), arg_count); 3516 __ CallRuntime(expr->function(), arg_count);
3517 OperandStackDepthDecrement(arg_count);
3532 context()->Plug(v0); 3518 context()->Plug(v0);
3533 } 3519 }
3534 } 3520 }
3535 } 3521 }
3536 } 3522 }
3537 3523
3538 3524
3539 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3525 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3540 switch (expr->op()) { 3526 switch (expr->op()) {
3541 case Token::DELETE: { 3527 case Token::DELETE: {
3542 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3528 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3543 Property* property = expr->expression()->AsProperty(); 3529 Property* property = expr->expression()->AsProperty();
3544 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3530 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3545 3531
3546 if (property != NULL) { 3532 if (property != NULL) {
3547 VisitForStackValue(property->obj()); 3533 VisitForStackValue(property->obj());
3548 VisitForStackValue(property->key()); 3534 VisitForStackValue(property->key());
3549 __ CallRuntime(is_strict(language_mode()) 3535 CallRuntimeWithOperands(is_strict(language_mode())
3550 ? Runtime::kDeleteProperty_Strict 3536 ? Runtime::kDeleteProperty_Strict
3551 : Runtime::kDeleteProperty_Sloppy); 3537 : Runtime::kDeleteProperty_Sloppy);
3552 context()->Plug(v0); 3538 context()->Plug(v0);
3553 } else if (proxy != NULL) { 3539 } else if (proxy != NULL) {
3554 Variable* var = proxy->var(); 3540 Variable* var = proxy->var();
3555 // Delete of an unqualified identifier is disallowed in strict mode but 3541 // Delete of an unqualified identifier is disallowed in strict mode but
3556 // "delete this" is allowed. 3542 // "delete this" is allowed.
3557 bool is_this = var->HasThisName(isolate()); 3543 bool is_this = var->HasThisName(isolate());
3558 DCHECK(is_sloppy(language_mode()) || is_this); 3544 DCHECK(is_sloppy(language_mode()) || is_this);
3559 if (var->IsUnallocatedOrGlobalSlot()) { 3545 if (var->IsUnallocatedOrGlobalSlot()) {
3560 __ LoadGlobalObject(a2); 3546 __ LoadGlobalObject(a2);
3561 __ li(a1, Operand(var->name())); 3547 __ li(a1, Operand(var->name()));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3608 // We handle value contexts explicitly rather than simply visiting 3594 // We handle value contexts explicitly rather than simply visiting
3609 // for control and plugging the control flow into the context, 3595 // for control and plugging the control flow into the context,
3610 // because we need to prepare a pair of extra administrative AST ids 3596 // because we need to prepare a pair of extra administrative AST ids
3611 // for the optimizing compiler. 3597 // for the optimizing compiler.
3612 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3598 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3613 Label materialize_true, materialize_false, done; 3599 Label materialize_true, materialize_false, done;
3614 VisitForControl(expr->expression(), 3600 VisitForControl(expr->expression(),
3615 &materialize_false, 3601 &materialize_false,
3616 &materialize_true, 3602 &materialize_true,
3617 &materialize_true); 3603 &materialize_true);
3604 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3618 __ bind(&materialize_true); 3605 __ bind(&materialize_true);
3619 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3606 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3620 __ LoadRoot(v0, Heap::kTrueValueRootIndex); 3607 __ LoadRoot(v0, Heap::kTrueValueRootIndex);
3621 if (context()->IsStackValue()) __ push(v0); 3608 if (context()->IsStackValue()) __ push(v0);
3622 __ jmp(&done); 3609 __ jmp(&done);
3623 __ bind(&materialize_false); 3610 __ bind(&materialize_false);
3624 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3611 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
3625 __ LoadRoot(v0, Heap::kFalseValueRootIndex); 3612 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
3626 if (context()->IsStackValue()) __ push(v0); 3613 if (context()->IsStackValue()) __ push(v0);
3627 __ bind(&done); 3614 __ bind(&done);
(...skipping 30 matching lines...) Expand all
3658 3645
3659 // Evaluate expression and get value. 3646 // Evaluate expression and get value.
3660 if (assign_type == VARIABLE) { 3647 if (assign_type == VARIABLE) {
3661 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3648 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3662 AccumulatorValueContext context(this); 3649 AccumulatorValueContext context(this);
3663 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3650 EmitVariableLoad(expr->expression()->AsVariableProxy());
3664 } else { 3651 } else {
3665 // Reserve space for result of postfix operation. 3652 // Reserve space for result of postfix operation.
3666 if (expr->is_postfix() && !context()->IsEffect()) { 3653 if (expr->is_postfix() && !context()->IsEffect()) {
3667 __ li(at, Operand(Smi::FromInt(0))); 3654 __ li(at, Operand(Smi::FromInt(0)));
3668 __ push(at); 3655 PushOperand(at);
3669 } 3656 }
3670 switch (assign_type) { 3657 switch (assign_type) {
3671 case NAMED_PROPERTY: { 3658 case NAMED_PROPERTY: {
3672 // Put the object both on the stack and in the register. 3659 // Put the object both on the stack and in the register.
3673 VisitForStackValue(prop->obj()); 3660 VisitForStackValue(prop->obj());
3674 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 3661 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
3675 EmitNamedPropertyLoad(prop); 3662 EmitNamedPropertyLoad(prop);
3676 break; 3663 break;
3677 } 3664 }
3678 3665
3679 case NAMED_SUPER_PROPERTY: { 3666 case NAMED_SUPER_PROPERTY: {
3680 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3667 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3681 VisitForAccumulatorValue( 3668 VisitForAccumulatorValue(
3682 prop->obj()->AsSuperPropertyReference()->home_object()); 3669 prop->obj()->AsSuperPropertyReference()->home_object());
3683 __ Push(result_register()); 3670 PushOperand(result_register());
3684 const Register scratch = a1; 3671 const Register scratch = a1;
3685 __ ld(scratch, MemOperand(sp, kPointerSize)); 3672 __ ld(scratch, MemOperand(sp, kPointerSize));
3686 __ Push(scratch, result_register()); 3673 PushOperands(scratch, result_register());
3687 EmitNamedSuperPropertyLoad(prop); 3674 EmitNamedSuperPropertyLoad(prop);
3688 break; 3675 break;
3689 } 3676 }
3690 3677
3691 case KEYED_SUPER_PROPERTY: { 3678 case KEYED_SUPER_PROPERTY: {
3692 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3679 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3693 VisitForAccumulatorValue( 3680 VisitForAccumulatorValue(
3694 prop->obj()->AsSuperPropertyReference()->home_object()); 3681 prop->obj()->AsSuperPropertyReference()->home_object());
3695 const Register scratch = a1; 3682 const Register scratch = a1;
3696 const Register scratch1 = a4; 3683 const Register scratch1 = a4;
3697 __ Move(scratch, result_register()); 3684 __ Move(scratch, result_register());
3698 VisitForAccumulatorValue(prop->key()); 3685 VisitForAccumulatorValue(prop->key());
3699 __ Push(scratch, result_register()); 3686 PushOperands(scratch, result_register());
3700 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize)); 3687 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize));
3701 __ Push(scratch1, scratch, result_register()); 3688 PushOperands(scratch1, scratch, result_register());
3702 EmitKeyedSuperPropertyLoad(prop); 3689 EmitKeyedSuperPropertyLoad(prop);
3703 break; 3690 break;
3704 } 3691 }
3705 3692
3706 case KEYED_PROPERTY: { 3693 case KEYED_PROPERTY: {
3707 VisitForStackValue(prop->obj()); 3694 VisitForStackValue(prop->obj());
3708 VisitForStackValue(prop->key()); 3695 VisitForStackValue(prop->key());
3709 __ ld(LoadDescriptor::ReceiverRegister(), 3696 __ ld(LoadDescriptor::ReceiverRegister(),
3710 MemOperand(sp, 1 * kPointerSize)); 3697 MemOperand(sp, 1 * kPointerSize));
3711 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); 3698 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3779 } 3766 }
3780 3767
3781 // Save result for postfix expressions. 3768 // Save result for postfix expressions.
3782 if (expr->is_postfix()) { 3769 if (expr->is_postfix()) {
3783 if (!context()->IsEffect()) { 3770 if (!context()->IsEffect()) {
3784 // Save the result on the stack. If we have a named or keyed property 3771 // Save the result on the stack. If we have a named or keyed property
3785 // we store the result under the receiver that is currently on top 3772 // we store the result under the receiver that is currently on top
3786 // of the stack. 3773 // of the stack.
3787 switch (assign_type) { 3774 switch (assign_type) {
3788 case VARIABLE: 3775 case VARIABLE:
3789 __ push(v0); 3776 PushOperand(v0);
3790 break; 3777 break;
3791 case NAMED_PROPERTY: 3778 case NAMED_PROPERTY:
3792 __ sd(v0, MemOperand(sp, kPointerSize)); 3779 __ sd(v0, MemOperand(sp, kPointerSize));
3793 break; 3780 break;
3794 case NAMED_SUPER_PROPERTY: 3781 case NAMED_SUPER_PROPERTY:
3795 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); 3782 __ sd(v0, MemOperand(sp, 2 * kPointerSize));
3796 break; 3783 break;
3797 case KEYED_PROPERTY: 3784 case KEYED_PROPERTY:
3798 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); 3785 __ sd(v0, MemOperand(sp, 2 * kPointerSize));
3799 break; 3786 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3837 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3824 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3838 Token::ASSIGN, expr->CountSlot()); 3825 Token::ASSIGN, expr->CountSlot());
3839 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3826 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3840 context()->Plug(v0); 3827 context()->Plug(v0);
3841 } 3828 }
3842 break; 3829 break;
3843 case NAMED_PROPERTY: { 3830 case NAMED_PROPERTY: {
3844 __ mov(StoreDescriptor::ValueRegister(), result_register()); 3831 __ mov(StoreDescriptor::ValueRegister(), result_register());
3845 __ li(StoreDescriptor::NameRegister(), 3832 __ li(StoreDescriptor::NameRegister(),
3846 Operand(prop->key()->AsLiteral()->value())); 3833 Operand(prop->key()->AsLiteral()->value()));
3847 __ pop(StoreDescriptor::ReceiverRegister()); 3834 PopOperand(StoreDescriptor::ReceiverRegister());
3848 EmitLoadStoreICSlot(expr->CountSlot()); 3835 EmitLoadStoreICSlot(expr->CountSlot());
3849 CallStoreIC(); 3836 CallStoreIC();
3850 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3837 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3851 if (expr->is_postfix()) { 3838 if (expr->is_postfix()) {
3852 if (!context()->IsEffect()) { 3839 if (!context()->IsEffect()) {
3853 context()->PlugTOS(); 3840 context()->PlugTOS();
3854 } 3841 }
3855 } else { 3842 } else {
3856 context()->Plug(v0); 3843 context()->Plug(v0);
3857 } 3844 }
(...skipping 16 matching lines...) Expand all
3874 if (!context()->IsEffect()) { 3861 if (!context()->IsEffect()) {
3875 context()->PlugTOS(); 3862 context()->PlugTOS();
3876 } 3863 }
3877 } else { 3864 } else {
3878 context()->Plug(v0); 3865 context()->Plug(v0);
3879 } 3866 }
3880 break; 3867 break;
3881 } 3868 }
3882 case KEYED_PROPERTY: { 3869 case KEYED_PROPERTY: {
3883 __ mov(StoreDescriptor::ValueRegister(), result_register()); 3870 __ mov(StoreDescriptor::ValueRegister(), result_register());
3884 __ Pop(StoreDescriptor::ReceiverRegister(), 3871 PopOperands(StoreDescriptor::ReceiverRegister(),
3885 StoreDescriptor::NameRegister()); 3872 StoreDescriptor::NameRegister());
3886 Handle<Code> ic = 3873 Handle<Code> ic =
3887 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3874 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3888 EmitLoadStoreICSlot(expr->CountSlot()); 3875 EmitLoadStoreICSlot(expr->CountSlot());
3889 CallIC(ic); 3876 CallIC(ic);
3890 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3877 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3891 if (expr->is_postfix()) { 3878 if (expr->is_postfix()) {
3892 if (!context()->IsEffect()) { 3879 if (!context()->IsEffect()) {
3893 context()->PlugTOS(); 3880 context()->PlugTOS();
3894 } 3881 }
3895 } else { 3882 } else {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3997 Label* if_false = NULL; 3984 Label* if_false = NULL;
3998 Label* fall_through = NULL; 3985 Label* fall_through = NULL;
3999 context()->PrepareTest(&materialize_true, &materialize_false, 3986 context()->PrepareTest(&materialize_true, &materialize_false,
4000 &if_true, &if_false, &fall_through); 3987 &if_true, &if_false, &fall_through);
4001 3988
4002 Token::Value op = expr->op(); 3989 Token::Value op = expr->op();
4003 VisitForStackValue(expr->left()); 3990 VisitForStackValue(expr->left());
4004 switch (op) { 3991 switch (op) {
4005 case Token::IN: 3992 case Token::IN:
4006 VisitForStackValue(expr->right()); 3993 VisitForStackValue(expr->right());
4007 __ CallRuntime(Runtime::kHasProperty); 3994 CallRuntimeWithOperands(Runtime::kHasProperty);
4008 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3995 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4009 __ LoadRoot(a4, Heap::kTrueValueRootIndex); 3996 __ LoadRoot(a4, Heap::kTrueValueRootIndex);
4010 Split(eq, v0, Operand(a4), if_true, if_false, fall_through); 3997 Split(eq, v0, Operand(a4), if_true, if_false, fall_through);
4011 break; 3998 break;
4012 3999
4013 case Token::INSTANCEOF: { 4000 case Token::INSTANCEOF: {
4014 VisitForAccumulatorValue(expr->right()); 4001 VisitForAccumulatorValue(expr->right());
4015 __ mov(a0, result_register()); 4002 __ mov(a0, result_register());
4016 __ pop(a1); 4003 PopOperand(a1);
4017 InstanceOfStub stub(isolate()); 4004 InstanceOfStub stub(isolate());
4018 __ CallStub(&stub); 4005 __ CallStub(&stub);
4019 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4006 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4020 __ LoadRoot(a4, Heap::kTrueValueRootIndex); 4007 __ LoadRoot(a4, Heap::kTrueValueRootIndex);
4021 Split(eq, v0, Operand(a4), if_true, if_false, fall_through); 4008 Split(eq, v0, Operand(a4), if_true, if_false, fall_through);
4022 break; 4009 break;
4023 } 4010 }
4024 4011
4025 default: { 4012 default: {
4026 VisitForAccumulatorValue(expr->right()); 4013 VisitForAccumulatorValue(expr->right());
4027 Condition cc = CompareIC::ComputeCondition(op); 4014 Condition cc = CompareIC::ComputeCondition(op);
4028 __ mov(a0, result_register()); 4015 __ mov(a0, result_register());
4029 __ pop(a1); 4016 PopOperand(a1);
4030 4017
4031 bool inline_smi_code = ShouldInlineSmiCase(op); 4018 bool inline_smi_code = ShouldInlineSmiCase(op);
4032 JumpPatchSite patch_site(masm_); 4019 JumpPatchSite patch_site(masm_);
4033 if (inline_smi_code) { 4020 if (inline_smi_code) {
4034 Label slow_case; 4021 Label slow_case;
4035 __ Or(a2, a0, Operand(a1)); 4022 __ Or(a2, a0, Operand(a1));
4036 patch_site.EmitJumpIfNotSmi(a2, &slow_case); 4023 patch_site.EmitJumpIfNotSmi(a2, &slow_case);
4037 Split(cc, a1, Operand(a0), if_true, if_false, NULL); 4024 Split(cc, a1, Operand(a0), if_true, if_false, NULL);
4038 __ bind(&slow_case); 4025 __ bind(&slow_case);
4039 } 4026 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4120 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, at); 4107 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, at);
4121 } else if (closure_scope->is_eval_scope()) { 4108 } else if (closure_scope->is_eval_scope()) {
4122 // Contexts created by a call to eval have the same closure as the 4109 // Contexts created by a call to eval have the same closure as the
4123 // context calling eval, not the anonymous closure containing the eval 4110 // context calling eval, not the anonymous closure containing the eval
4124 // code. Fetch it from the context. 4111 // code. Fetch it from the context.
4125 __ ld(at, ContextMemOperand(cp, Context::CLOSURE_INDEX)); 4112 __ ld(at, ContextMemOperand(cp, Context::CLOSURE_INDEX));
4126 } else { 4113 } else {
4127 DCHECK(closure_scope->is_function_scope()); 4114 DCHECK(closure_scope->is_function_scope());
4128 __ ld(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4115 __ ld(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4129 } 4116 }
4130 __ push(at); 4117 PushOperand(at);
4131 } 4118 }
4132 4119
4133 4120
4134 // ---------------------------------------------------------------------------- 4121 // ----------------------------------------------------------------------------
4135 // Non-local control flow support. 4122 // Non-local control flow support.
4136 4123
4137 void FullCodeGenerator::EnterFinallyBlock() { 4124 void FullCodeGenerator::EnterFinallyBlock() {
4138 DCHECK(!result_register().is(a1)); 4125 DCHECK(!result_register().is(a1));
4139 // Store pending message while executing finally block. 4126 // Store pending message while executing finally block.
4140 ExternalReference pending_message_obj = 4127 ExternalReference pending_message_obj =
4141 ExternalReference::address_of_pending_message_obj(isolate()); 4128 ExternalReference::address_of_pending_message_obj(isolate());
4142 __ li(at, Operand(pending_message_obj)); 4129 __ li(at, Operand(pending_message_obj));
4143 __ ld(a1, MemOperand(at)); 4130 __ ld(a1, MemOperand(at));
4144 __ push(a1); 4131 PushOperand(a1);
4145 4132
4146 ClearPendingMessage(); 4133 ClearPendingMessage();
4147 } 4134 }
4148 4135
4149 4136
4150 void FullCodeGenerator::ExitFinallyBlock() { 4137 void FullCodeGenerator::ExitFinallyBlock() {
4151 DCHECK(!result_register().is(a1)); 4138 DCHECK(!result_register().is(a1));
4152 // Restore pending message from stack. 4139 // Restore pending message from stack.
4153 __ pop(a1); 4140 PopOperand(a1);
4154 ExternalReference pending_message_obj = 4141 ExternalReference pending_message_obj =
4155 ExternalReference::address_of_pending_message_obj(isolate()); 4142 ExternalReference::address_of_pending_message_obj(isolate());
4156 __ li(at, Operand(pending_message_obj)); 4143 __ li(at, Operand(pending_message_obj));
4157 __ sd(a1, MemOperand(at)); 4144 __ sd(a1, MemOperand(at));
4158 } 4145 }
4159 4146
4160 4147
4161 void FullCodeGenerator::ClearPendingMessage() { 4148 void FullCodeGenerator::ClearPendingMessage() {
4162 DCHECK(!result_register().is(a1)); 4149 DCHECK(!result_register().is(a1));
4163 ExternalReference pending_message_obj = 4150 ExternalReference pending_message_obj =
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
4281 reinterpret_cast<uint64_t>( 4268 reinterpret_cast<uint64_t>(
4282 isolate->builtins()->OsrAfterStackCheck()->entry())); 4269 isolate->builtins()->OsrAfterStackCheck()->entry()));
4283 return OSR_AFTER_STACK_CHECK; 4270 return OSR_AFTER_STACK_CHECK;
4284 } 4271 }
4285 4272
4286 4273
4287 } // namespace internal 4274 } // namespace internal
4288 } // namespace v8 4275 } // namespace v8
4289 4276
4290 #endif // V8_TARGET_ARCH_MIPS64 4277 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/full-codegen/mips/full-codegen-mips.cc ('k') | src/full-codegen/ppc/full-codegen-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698