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

Side by Side Diff: src/full-codegen/mips/full-codegen-mips.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
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_MIPS 5 #if V8_TARGET_ARCH_MIPS
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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 134
135 info->set_prologue_offset(masm_->pc_offset()); 135 info->set_prologue_offset(masm_->pc_offset());
136 __ Prologue(info->GeneratePreagedPrologue()); 136 __ Prologue(info->GeneratePreagedPrologue());
137 137
138 { Comment cmnt(masm_, "[ Allocate locals"); 138 { Comment cmnt(masm_, "[ Allocate locals");
139 int locals_count = info->scope()->num_stack_slots(); 139 int locals_count = info->scope()->num_stack_slots();
140 // Generators allocate locals, if any, in context slots. 140 // Generators allocate locals, if any, in context slots.
141 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 141 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
142 OperandStackDepthIncrement(locals_count);
142 if (locals_count > 0) { 143 if (locals_count > 0) {
143 if (locals_count >= 128) { 144 if (locals_count >= 128) {
144 Label ok; 145 Label ok;
145 __ Subu(t5, sp, Operand(locals_count * kPointerSize)); 146 __ Subu(t5, sp, Operand(locals_count * kPointerSize));
146 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); 147 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
147 __ Branch(&ok, hs, t5, Operand(a2)); 148 __ Branch(&ok, hs, t5, Operand(a2));
148 __ CallRuntime(Runtime::kThrowStackOverflow); 149 __ CallRuntime(Runtime::kThrowStackOverflow);
149 __ bind(&ok); 150 __ bind(&ok);
150 } 151 }
151 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex); 152 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex);
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 masm_->Addu(sp, sp, Operand(sp_delta)); 459 masm_->Addu(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 __ sw(reg, MemOperand(sp, 0)); 559 __ sw(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 14 matching lines...) Expand all
1016 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 991 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
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. 997 // Get the object to enumerate over.
1023 SetExpressionAsStatementPosition(stmt->enumerable()); 998 SetExpressionAsStatementPosition(stmt->enumerable());
1024 VisitForAccumulatorValue(stmt->enumerable()); 999 VisitForAccumulatorValue(stmt->enumerable());
1025 __ mov(a0, result_register()); 1000 __ mov(a0, result_register());
1001 OperandStackDepthIncrement(ForIn::kElementCount);
1026 1002
1027 // If the object is null or undefined, skip over the loop, otherwise convert 1003 // If the object is null or undefined, skip over the loop, otherwise convert
1028 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 1004 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
1029 Label convert, done_convert; 1005 Label convert, done_convert;
1030 __ JumpIfSmi(a0, &convert); 1006 __ JumpIfSmi(a0, &convert);
1031 __ GetObjectType(a0, a1, a1); 1007 __ GetObjectType(a0, a1, a1);
1032 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, 1008 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1,
1033 Operand(FIRST_JS_RECEIVER_TYPE)); 1009 Operand(FIRST_JS_RECEIVER_TYPE));
1034 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. 1010 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot.
1035 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); 1011 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at));
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 __ bind(loop_statement.continue_label()); 1151 __ bind(loop_statement.continue_label());
1176 __ pop(a0); 1152 __ pop(a0);
1177 __ Addu(a0, a0, Operand(Smi::FromInt(1))); 1153 __ Addu(a0, a0, Operand(Smi::FromInt(1)));
1178 __ push(a0); 1154 __ push(a0);
1179 1155
1180 EmitBackEdgeBookkeeping(stmt, &loop); 1156 EmitBackEdgeBookkeeping(stmt, &loop);
1181 __ Branch(&loop); 1157 __ Branch(&loop);
1182 1158
1183 // Remove the pointers stored on the stack. 1159 // Remove the pointers stored on the stack.
1184 __ bind(loop_statement.break_label()); 1160 __ bind(loop_statement.break_label());
1185 __ Drop(5); 1161 DropOperands(5);
1186 1162
1187 // Exit and decrement the loop depth. 1163 // Exit and decrement the loop depth.
1188 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1164 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1189 __ bind(&exit); 1165 __ bind(&exit);
1190 decrement_loop_depth(); 1166 decrement_loop_depth();
1191 } 1167 }
1192 1168
1193 1169
1194 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1170 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1195 bool pretenure) { 1171 bool pretenure) {
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 FastCloneRegExpStub stub(isolate()); 1427 FastCloneRegExpStub stub(isolate());
1452 __ CallStub(&stub); 1428 __ CallStub(&stub);
1453 context()->Plug(v0); 1429 context()->Plug(v0);
1454 } 1430 }
1455 1431
1456 1432
1457 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1433 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1458 Expression* expression = (property == NULL) ? NULL : property->value(); 1434 Expression* expression = (property == NULL) ? NULL : property->value();
1459 if (expression == NULL) { 1435 if (expression == NULL) {
1460 __ LoadRoot(a1, Heap::kNullValueRootIndex); 1436 __ LoadRoot(a1, Heap::kNullValueRootIndex);
1461 __ push(a1); 1437 PushOperand(a1);
1462 } else { 1438 } else {
1463 VisitForStackValue(expression); 1439 VisitForStackValue(expression);
1464 if (NeedsHomeObject(expression)) { 1440 if (NeedsHomeObject(expression)) {
1465 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1441 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1466 property->kind() == ObjectLiteral::Property::SETTER); 1442 property->kind() == ObjectLiteral::Property::SETTER);
1467 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1443 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1468 EmitSetHomeObject(expression, offset, property->GetSlot()); 1444 EmitSetHomeObject(expression, offset, property->GetSlot());
1469 } 1445 }
1470 } 1446 }
1471 } 1447 }
(...skipping 23 matching lines...) Expand all
1495 AccessorTable accessor_table(zone()); 1471 AccessorTable accessor_table(zone());
1496 int property_index = 0; 1472 int property_index = 0;
1497 for (; property_index < expr->properties()->length(); property_index++) { 1473 for (; property_index < expr->properties()->length(); property_index++) {
1498 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1474 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1499 if (property->is_computed_name()) break; 1475 if (property->is_computed_name()) break;
1500 if (property->IsCompileTimeValue()) continue; 1476 if (property->IsCompileTimeValue()) continue;
1501 1477
1502 Literal* key = property->key()->AsLiteral(); 1478 Literal* key = property->key()->AsLiteral();
1503 Expression* value = property->value(); 1479 Expression* value = property->value();
1504 if (!result_saved) { 1480 if (!result_saved) {
1505 __ push(v0); // Save result on stack. 1481 PushOperand(v0); // Save result on stack.
1506 result_saved = true; 1482 result_saved = true;
1507 } 1483 }
1508 switch (property->kind()) { 1484 switch (property->kind()) {
1509 case ObjectLiteral::Property::CONSTANT: 1485 case ObjectLiteral::Property::CONSTANT:
1510 UNREACHABLE(); 1486 UNREACHABLE();
1511 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1487 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1512 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1488 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1513 // Fall through. 1489 // Fall through.
1514 case ObjectLiteral::Property::COMPUTED: 1490 case ObjectLiteral::Property::COMPUTED:
1515 // It is safe to use [[Put]] here because the boilerplate already 1491 // It is safe to use [[Put]] here because the boilerplate already
(...skipping 12 matching lines...) Expand all
1528 if (NeedsHomeObject(value)) { 1504 if (NeedsHomeObject(value)) {
1529 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1505 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1530 } 1506 }
1531 } else { 1507 } else {
1532 VisitForEffect(value); 1508 VisitForEffect(value);
1533 } 1509 }
1534 break; 1510 break;
1535 } 1511 }
1536 // Duplicate receiver on stack. 1512 // Duplicate receiver on stack.
1537 __ lw(a0, MemOperand(sp)); 1513 __ lw(a0, MemOperand(sp));
1538 __ push(a0); 1514 PushOperand(a0);
1539 VisitForStackValue(key); 1515 VisitForStackValue(key);
1540 VisitForStackValue(value); 1516 VisitForStackValue(value);
1541 if (property->emit_store()) { 1517 if (property->emit_store()) {
1542 if (NeedsHomeObject(value)) { 1518 if (NeedsHomeObject(value)) {
1543 EmitSetHomeObject(value, 2, property->GetSlot()); 1519 EmitSetHomeObject(value, 2, property->GetSlot());
1544 } 1520 }
1545 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. 1521 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes.
1546 __ push(a0); 1522 PushOperand(a0);
1547 __ CallRuntime(Runtime::kSetProperty); 1523 CallRuntimeWithOperands(Runtime::kSetProperty);
1548 } else { 1524 } else {
1549 __ Drop(3); 1525 DropOperands(3);
1550 } 1526 }
1551 break; 1527 break;
1552 case ObjectLiteral::Property::PROTOTYPE: 1528 case ObjectLiteral::Property::PROTOTYPE:
1553 // Duplicate receiver on stack. 1529 // Duplicate receiver on stack.
1554 __ lw(a0, MemOperand(sp)); 1530 __ lw(a0, MemOperand(sp));
1555 __ push(a0); 1531 PushOperand(a0);
1556 VisitForStackValue(value); 1532 VisitForStackValue(value);
1557 DCHECK(property->emit_store()); 1533 DCHECK(property->emit_store());
1558 __ CallRuntime(Runtime::kInternalSetPrototype); 1534 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1559 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1535 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1560 NO_REGISTERS); 1536 NO_REGISTERS);
1561 break; 1537 break;
1562 case ObjectLiteral::Property::GETTER: 1538 case ObjectLiteral::Property::GETTER:
1563 if (property->emit_store()) { 1539 if (property->emit_store()) {
1564 accessor_table.lookup(key)->second->getter = property; 1540 accessor_table.lookup(key)->second->getter = property;
1565 } 1541 }
1566 break; 1542 break;
1567 case ObjectLiteral::Property::SETTER: 1543 case ObjectLiteral::Property::SETTER:
1568 if (property->emit_store()) { 1544 if (property->emit_store()) {
1569 accessor_table.lookup(key)->second->setter = property; 1545 accessor_table.lookup(key)->second->setter = property;
1570 } 1546 }
1571 break; 1547 break;
1572 } 1548 }
1573 } 1549 }
1574 1550
1575 // Emit code to define accessors, using only a single call to the runtime for 1551 // Emit code to define accessors, using only a single call to the runtime for
1576 // each pair of corresponding getters and setters. 1552 // each pair of corresponding getters and setters.
1577 for (AccessorTable::Iterator it = accessor_table.begin(); 1553 for (AccessorTable::Iterator it = accessor_table.begin();
1578 it != accessor_table.end(); 1554 it != accessor_table.end();
1579 ++it) { 1555 ++it) {
1580 __ lw(a0, MemOperand(sp)); // Duplicate receiver. 1556 __ lw(a0, MemOperand(sp)); // Duplicate receiver.
1581 __ push(a0); 1557 PushOperand(a0);
1582 VisitForStackValue(it->first); 1558 VisitForStackValue(it->first);
1583 EmitAccessor(it->second->getter); 1559 EmitAccessor(it->second->getter);
1584 EmitAccessor(it->second->setter); 1560 EmitAccessor(it->second->setter);
1585 __ li(a0, Operand(Smi::FromInt(NONE))); 1561 __ li(a0, Operand(Smi::FromInt(NONE)));
1586 __ push(a0); 1562 PushOperand(a0);
1587 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1563 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1588 } 1564 }
1589 1565
1590 // Object literals have two parts. The "static" part on the left contains no 1566 // Object literals have two parts. The "static" part on the left contains no
1591 // computed property names, and so we can compute its map ahead of time; see 1567 // computed property names, and so we can compute its map ahead of time; see
1592 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1568 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1593 // starts with the first computed property name, and continues with all 1569 // starts with the first computed property name, and continues with all
1594 // properties to its right. All the code from above initializes the static 1570 // properties to its right. All the code from above initializes the static
1595 // component of the object literal, and arranges for the map of the result to 1571 // component of the object literal, and arranges for the map of the result to
1596 // reflect the static order in which the keys appear. For the dynamic 1572 // reflect the static order in which the keys appear. For the dynamic
1597 // properties, we compile them into a series of "SetOwnProperty" runtime 1573 // properties, we compile them into a series of "SetOwnProperty" runtime
1598 // calls. This will preserve insertion order. 1574 // calls. This will preserve insertion order.
1599 for (; property_index < expr->properties()->length(); property_index++) { 1575 for (; property_index < expr->properties()->length(); property_index++) {
1600 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1576 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1601 1577
1602 Expression* value = property->value(); 1578 Expression* value = property->value();
1603 if (!result_saved) { 1579 if (!result_saved) {
1604 __ push(v0); // Save result on the stack 1580 PushOperand(v0); // Save result on the stack
1605 result_saved = true; 1581 result_saved = true;
1606 } 1582 }
1607 1583
1608 __ lw(a0, MemOperand(sp)); // Duplicate receiver. 1584 __ lw(a0, MemOperand(sp)); // Duplicate receiver.
1609 __ push(a0); 1585 PushOperand(a0);
1610 1586
1611 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1587 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1612 DCHECK(!property->is_computed_name()); 1588 DCHECK(!property->is_computed_name());
1613 VisitForStackValue(value); 1589 VisitForStackValue(value);
1614 DCHECK(property->emit_store()); 1590 DCHECK(property->emit_store());
1615 __ CallRuntime(Runtime::kInternalSetPrototype); 1591 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1616 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1592 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1617 NO_REGISTERS); 1593 NO_REGISTERS);
1618 } else { 1594 } else {
1619 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1595 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1620 VisitForStackValue(value); 1596 VisitForStackValue(value);
1621 if (NeedsHomeObject(value)) { 1597 if (NeedsHomeObject(value)) {
1622 EmitSetHomeObject(value, 2, property->GetSlot()); 1598 EmitSetHomeObject(value, 2, property->GetSlot());
1623 } 1599 }
1624 1600
1625 switch (property->kind()) { 1601 switch (property->kind()) {
1626 case ObjectLiteral::Property::CONSTANT: 1602 case ObjectLiteral::Property::CONSTANT:
1627 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1603 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1628 case ObjectLiteral::Property::COMPUTED: 1604 case ObjectLiteral::Property::COMPUTED:
1629 if (property->emit_store()) { 1605 if (property->emit_store()) {
1630 __ Push(Smi::FromInt(NONE)); 1606 PushOperand(Smi::FromInt(NONE));
1631 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1607 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1632 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1608 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1633 } else { 1609 } else {
1634 __ Drop(3); 1610 DropOperands(3);
1635 } 1611 }
1636 break; 1612 break;
1637 1613
1638 case ObjectLiteral::Property::PROTOTYPE: 1614 case ObjectLiteral::Property::PROTOTYPE:
1639 UNREACHABLE(); 1615 UNREACHABLE();
1640 break; 1616 break;
1641 1617
1642 case ObjectLiteral::Property::GETTER: 1618 case ObjectLiteral::Property::GETTER:
1643 __ Push(Smi::FromInt(NONE)); 1619 PushOperand(Smi::FromInt(NONE));
1644 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1620 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1645 break; 1621 break;
1646 1622
1647 case ObjectLiteral::Property::SETTER: 1623 case ObjectLiteral::Property::SETTER:
1648 __ Push(Smi::FromInt(NONE)); 1624 PushOperand(Smi::FromInt(NONE));
1649 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1625 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1650 break; 1626 break;
1651 } 1627 }
1652 } 1628 }
1653 } 1629 }
1654 1630
1655 if (expr->has_function()) { 1631 if (expr->has_function()) {
1656 DCHECK(result_saved); 1632 DCHECK(result_saved);
1657 __ lw(a0, MemOperand(sp)); 1633 __ lw(a0, MemOperand(sp));
1658 __ push(a0); 1634 __ push(a0);
1659 __ CallRuntime(Runtime::kToFastProperties); 1635 __ CallRuntime(Runtime::kToFastProperties);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 int array_index = 0; 1680 int array_index = 0;
1705 for (; array_index < length; array_index++) { 1681 for (; array_index < length; array_index++) {
1706 Expression* subexpr = subexprs->at(array_index); 1682 Expression* subexpr = subexprs->at(array_index);
1707 DCHECK(!subexpr->IsSpread()); 1683 DCHECK(!subexpr->IsSpread());
1708 1684
1709 // If the subexpression is a literal or a simple materialized literal it 1685 // If the subexpression is a literal or a simple materialized literal it
1710 // is already set in the cloned array. 1686 // is already set in the cloned array.
1711 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1687 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1712 1688
1713 if (!result_saved) { 1689 if (!result_saved) {
1714 __ push(v0); // array literal 1690 PushOperand(v0); // array literal
1715 result_saved = true; 1691 result_saved = true;
1716 } 1692 }
1717 1693
1718 VisitForAccumulatorValue(subexpr); 1694 VisitForAccumulatorValue(subexpr);
1719 1695
1720 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); 1696 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index)));
1721 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1697 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1722 __ mov(StoreDescriptor::ValueRegister(), result_register()); 1698 __ mov(StoreDescriptor::ValueRegister(), result_register());
1723 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1699 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1724 Handle<Code> ic = 1700 Handle<Code> ic =
1725 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1701 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1726 CallIC(ic); 1702 CallIC(ic);
1727 1703
1728 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1704 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1729 } 1705 }
1730 1706
1731 // In case the array literal contains spread expressions it has two parts. The 1707 // In case the array literal contains spread expressions it has two parts. The
1732 // first part is the "static" array which has a literal index is handled 1708 // first part is the "static" array which has a literal index is handled
1733 // above. The second part is the part after the first spread expression 1709 // above. The second part is the part after the first spread expression
1734 // (inclusive) and these elements gets appended to the array. Note that the 1710 // (inclusive) and these elements gets appended to the array. Note that the
1735 // number elements an iterable produces is unknown ahead of time. 1711 // number elements an iterable produces is unknown ahead of time.
1736 if (array_index < length && result_saved) { 1712 if (array_index < length && result_saved) {
1737 __ Pop(v0); 1713 PopOperand(v0);
1738 result_saved = false; 1714 result_saved = false;
1739 } 1715 }
1740 for (; array_index < length; array_index++) { 1716 for (; array_index < length; array_index++) {
1741 Expression* subexpr = subexprs->at(array_index); 1717 Expression* subexpr = subexprs->at(array_index);
1742 1718
1743 __ Push(v0); 1719 PushOperand(v0);
1744 DCHECK(!subexpr->IsSpread()); 1720 DCHECK(!subexpr->IsSpread());
1745 VisitForStackValue(subexpr); 1721 VisitForStackValue(subexpr);
1746 __ CallRuntime(Runtime::kAppendElement); 1722 CallRuntimeWithOperands(Runtime::kAppendElement);
1747 1723
1748 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1724 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1749 } 1725 }
1750 1726
1751 if (result_saved) { 1727 if (result_saved) {
1752 context()->PlugTOS(); 1728 context()->PlugTOS();
1753 } else { 1729 } else {
1754 context()->Plug(v0); 1730 context()->Plug(v0);
1755 } 1731 }
1756 } 1732 }
(...skipping 20 matching lines...) Expand all
1777 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1753 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1778 } else { 1754 } else {
1779 VisitForStackValue(property->obj()); 1755 VisitForStackValue(property->obj());
1780 } 1756 }
1781 break; 1757 break;
1782 case NAMED_SUPER_PROPERTY: 1758 case NAMED_SUPER_PROPERTY:
1783 VisitForStackValue( 1759 VisitForStackValue(
1784 property->obj()->AsSuperPropertyReference()->this_var()); 1760 property->obj()->AsSuperPropertyReference()->this_var());
1785 VisitForAccumulatorValue( 1761 VisitForAccumulatorValue(
1786 property->obj()->AsSuperPropertyReference()->home_object()); 1762 property->obj()->AsSuperPropertyReference()->home_object());
1787 __ Push(result_register()); 1763 PushOperand(result_register());
1788 if (expr->is_compound()) { 1764 if (expr->is_compound()) {
1789 const Register scratch = a1; 1765 const Register scratch = a1;
1790 __ lw(scratch, MemOperand(sp, kPointerSize)); 1766 __ lw(scratch, MemOperand(sp, kPointerSize));
1791 __ Push(scratch, result_register()); 1767 PushOperands(scratch, result_register());
1792 } 1768 }
1793 break; 1769 break;
1794 case KEYED_SUPER_PROPERTY: { 1770 case KEYED_SUPER_PROPERTY: {
1795 const Register scratch = a1; 1771 const Register scratch = a1;
1796 VisitForStackValue( 1772 VisitForStackValue(
1797 property->obj()->AsSuperPropertyReference()->this_var()); 1773 property->obj()->AsSuperPropertyReference()->this_var());
1798 VisitForAccumulatorValue( 1774 VisitForAccumulatorValue(
1799 property->obj()->AsSuperPropertyReference()->home_object()); 1775 property->obj()->AsSuperPropertyReference()->home_object());
1800 __ Move(scratch, result_register()); 1776 __ Move(scratch, result_register());
1801 VisitForAccumulatorValue(property->key()); 1777 VisitForAccumulatorValue(property->key());
1802 __ Push(scratch, result_register()); 1778 PushOperands(scratch, result_register());
1803 if (expr->is_compound()) { 1779 if (expr->is_compound()) {
1804 const Register scratch1 = t0; 1780 const Register scratch1 = t0;
1805 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize)); 1781 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize));
1806 __ Push(scratch1, scratch, result_register()); 1782 PushOperands(scratch1, scratch, result_register());
1807 } 1783 }
1808 break; 1784 break;
1809 } 1785 }
1810 case KEYED_PROPERTY: 1786 case KEYED_PROPERTY:
1811 // We need the key and receiver on both the stack and in v0 and a1. 1787 // We need the key and receiver on both the stack and in v0 and a1.
1812 if (expr->is_compound()) { 1788 if (expr->is_compound()) {
1813 VisitForStackValue(property->obj()); 1789 VisitForStackValue(property->obj());
1814 VisitForStackValue(property->key()); 1790 VisitForStackValue(property->key());
1815 __ lw(LoadDescriptor::ReceiverRegister(), 1791 __ lw(LoadDescriptor::ReceiverRegister(),
1816 MemOperand(sp, 1 * kPointerSize)); 1792 MemOperand(sp, 1 * kPointerSize));
(...skipping 27 matching lines...) Expand all
1844 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1820 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1845 break; 1821 break;
1846 case KEYED_PROPERTY: 1822 case KEYED_PROPERTY:
1847 EmitKeyedPropertyLoad(property); 1823 EmitKeyedPropertyLoad(property);
1848 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1824 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1849 break; 1825 break;
1850 } 1826 }
1851 } 1827 }
1852 1828
1853 Token::Value op = expr->binary_op(); 1829 Token::Value op = expr->binary_op();
1854 __ push(v0); // Left operand goes on the stack. 1830 PushOperand(v0); // Left operand goes on the stack.
1855 VisitForAccumulatorValue(expr->value()); 1831 VisitForAccumulatorValue(expr->value());
1856 1832
1857 AccumulatorValueContext context(this); 1833 AccumulatorValueContext context(this);
1858 if (ShouldInlineSmiCase(op)) { 1834 if (ShouldInlineSmiCase(op)) {
1859 EmitInlineSmiBinaryOp(expr->binary_operation(), 1835 EmitInlineSmiBinaryOp(expr->binary_operation(),
1860 op, 1836 op,
1861 expr->target(), 1837 expr->target(),
1862 expr->value()); 1838 expr->value());
1863 } else { 1839 } else {
1864 EmitBinaryOp(expr->binary_operation(), op); 1840 EmitBinaryOp(expr->binary_operation(), op);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1936 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); 1912 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
1937 __ mov(a1, cp); 1913 __ mov(a1, cp);
1938 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, 1914 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2,
1939 kRAHasBeenSaved, kDontSaveFPRegs); 1915 kRAHasBeenSaved, kDontSaveFPRegs);
1940 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1916 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1941 __ Branch(&post_runtime, eq, sp, Operand(a1)); 1917 __ Branch(&post_runtime, eq, sp, Operand(a1));
1942 __ push(v0); // generator object 1918 __ push(v0); // generator object
1943 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1919 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1944 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1920 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1945 __ bind(&post_runtime); 1921 __ bind(&post_runtime);
1946 __ pop(result_register()); 1922 PopOperand(result_register());
1947 EmitReturnSequence(); 1923 EmitReturnSequence();
1948 1924
1949 __ bind(&resume); 1925 __ bind(&resume);
1950 context()->Plug(result_register()); 1926 context()->Plug(result_register());
1951 break; 1927 break;
1952 } 1928 }
1953 1929
1954 case Yield::kFinal: { 1930 case Yield::kFinal: {
1955 // Pop value from top-of-stack slot, box result into result register. 1931 // Pop value from top-of-stack slot, box result into result register.
1932 OperandStackDepthDecrement(1);
1956 EmitCreateIteratorResult(true); 1933 EmitCreateIteratorResult(true);
1957 EmitUnwindAndReturn(); 1934 EmitUnwindAndReturn();
1958 break; 1935 break;
1959 } 1936 }
1960 1937
1961 case Yield::kDelegating: 1938 case Yield::kDelegating:
1962 UNREACHABLE(); 1939 UNREACHABLE();
1963 } 1940 }
1964 } 1941 }
1965 1942
1966 1943
1967 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 1944 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1968 Expression *value, 1945 Expression *value,
1969 JSGeneratorObject::ResumeMode resume_mode) { 1946 JSGeneratorObject::ResumeMode resume_mode) {
1970 // The value stays in a0, and is ultimately read by the resumed generator, as 1947 // The value stays in a0, and is ultimately read by the resumed generator, as
1971 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1948 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1972 // is read to throw the value when the resumed generator is already closed. 1949 // is read to throw the value when the resumed generator is already closed.
1973 // a1 will hold the generator object until the activation has been resumed. 1950 // a1 will hold the generator object until the activation has been resumed.
1974 VisitForStackValue(generator); 1951 VisitForStackValue(generator);
1975 VisitForAccumulatorValue(value); 1952 VisitForAccumulatorValue(value);
1976 __ pop(a1); 1953 PopOperand(a1);
1977 1954
1978 // Store input value into generator object. 1955 // Store input value into generator object.
1979 __ sw(result_register(), 1956 __ sw(result_register(),
1980 FieldMemOperand(a1, JSGeneratorObject::kInputOffset)); 1957 FieldMemOperand(a1, JSGeneratorObject::kInputOffset));
1981 __ mov(a2, result_register()); 1958 __ mov(a2, result_register());
1982 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3, 1959 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3,
1983 kRAHasBeenSaved, kDontSaveFPRegs); 1960 kRAHasBeenSaved, kDontSaveFPRegs);
1984 1961
1985 // Load suspended function and context. 1962 // Load suspended function and context.
1986 __ lw(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset)); 1963 __ lw(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 __ Push(a1, result_register()); 2029 __ Push(a1, result_register());
2053 __ Push(Smi::FromInt(resume_mode)); 2030 __ Push(Smi::FromInt(resume_mode));
2054 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 2031 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
2055 // Not reached: the runtime call returns elsewhere. 2032 // Not reached: the runtime call returns elsewhere.
2056 __ stop("not-reached"); 2033 __ stop("not-reached");
2057 2034
2058 __ bind(&done); 2035 __ bind(&done);
2059 context()->Plug(result_register()); 2036 context()->Plug(result_register());
2060 } 2037 }
2061 2038
2039 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
2040 OperandStackDepthIncrement(2);
2041 __ Push(reg1, reg2);
2042 }
2043
2044 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
2045 Register reg3) {
2046 OperandStackDepthIncrement(3);
2047 __ Push(reg1, reg2, reg3);
2048 }
2049
2050 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
2051 Register reg3, Register reg4) {
2052 OperandStackDepthIncrement(4);
2053 __ Push(reg1, reg2, reg3, reg4);
2054 }
2055
2056 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) {
2057 OperandStackDepthDecrement(2);
2058 __ Pop(reg1, reg2);
2059 }
2060
2061 void FullCodeGenerator::EmitOperandStackDepthCheck() {
2062 if (FLAG_debug_code) {
2063 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
2064 operand_stack_depth_ * kPointerSize;
2065 __ Subu(v0, fp, sp);
2066 __ Assert(eq, kUnexpectedStackDepth, v0, Operand(expected_diff));
2067 }
2068 }
2062 2069
2063 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2070 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2064 Label allocate, done_allocate; 2071 Label allocate, done_allocate;
2065 2072
2066 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); 2073 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
2067 __ jmp(&done_allocate); 2074 __ jmp(&done_allocate);
2068 2075
2069 __ bind(&allocate); 2076 __ bind(&allocate);
2070 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2077 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2071 __ CallRuntime(Runtime::kAllocateInNewSpace); 2078 __ CallRuntime(Runtime::kAllocateInNewSpace);
(...skipping 18 matching lines...) Expand all
2090 Literal* key = prop->key()->AsLiteral(); 2097 Literal* key = prop->key()->AsLiteral();
2091 DCHECK(!prop->IsSuperAccess()); 2098 DCHECK(!prop->IsSuperAccess());
2092 2099
2093 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); 2100 __ li(LoadDescriptor::NameRegister(), Operand(key->value()));
2094 __ li(LoadDescriptor::SlotRegister(), 2101 __ li(LoadDescriptor::SlotRegister(),
2095 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2102 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2096 CallLoadIC(NOT_INSIDE_TYPEOF); 2103 CallLoadIC(NOT_INSIDE_TYPEOF);
2097 } 2104 }
2098 2105
2099 2106
2100 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2101 // Stack: receiver, home_object.
2102 SetExpressionPosition(prop);
2103
2104 Literal* key = prop->key()->AsLiteral();
2105 DCHECK(!key->value()->IsSmi());
2106 DCHECK(prop->IsSuperAccess());
2107
2108 __ Push(key->value());
2109 __ CallRuntime(Runtime::kLoadFromSuper);
2110 }
2111
2112
2113 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2114 SetExpressionPosition(prop);
2115 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2116 __ li(LoadDescriptor::SlotRegister(),
2117 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2118 CallIC(ic);
2119 }
2120
2121
2122 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2123 // Stack: receiver, home_object, key.
2124 SetExpressionPosition(prop);
2125 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2126 }
2127
2128
2129 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2107 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2130 Token::Value op, 2108 Token::Value op,
2131 Expression* left_expr, 2109 Expression* left_expr,
2132 Expression* right_expr) { 2110 Expression* right_expr) {
2133 Label done, smi_case, stub_call; 2111 Label done, smi_case, stub_call;
2134 2112
2135 Register scratch1 = a2; 2113 Register scratch1 = a2;
2136 Register scratch2 = a3; 2114 Register scratch2 = a3;
2137 2115
2138 // Get the arguments. 2116 // Get the arguments.
2139 Register left = a1; 2117 Register left = a1;
2140 Register right = a0; 2118 Register right = a0;
2141 __ pop(left); 2119 PopOperand(left);
2142 __ mov(a0, result_register()); 2120 __ mov(a0, result_register());
2143 2121
2144 // Perform combined smi check on both operands. 2122 // Perform combined smi check on both operands.
2145 __ Or(scratch1, left, Operand(right)); 2123 __ Or(scratch1, left, Operand(right));
2146 STATIC_ASSERT(kSmiTag == 0); 2124 STATIC_ASSERT(kSmiTag == 0);
2147 JumpPatchSite patch_site(masm_); 2125 JumpPatchSite patch_site(masm_);
2148 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2126 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2149 2127
2150 __ bind(&stub_call); 2128 __ bind(&stub_call);
2151 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2129 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2220 for (int i = 0; i < lit->properties()->length(); i++) { 2198 for (int i = 0; i < lit->properties()->length(); i++) {
2221 ObjectLiteral::Property* property = lit->properties()->at(i); 2199 ObjectLiteral::Property* property = lit->properties()->at(i);
2222 Expression* value = property->value(); 2200 Expression* value = property->value();
2223 2201
2224 Register scratch = a1; 2202 Register scratch = a1;
2225 if (property->is_static()) { 2203 if (property->is_static()) {
2226 __ lw(scratch, MemOperand(sp, kPointerSize)); // constructor 2204 __ lw(scratch, MemOperand(sp, kPointerSize)); // constructor
2227 } else { 2205 } else {
2228 __ lw(scratch, MemOperand(sp, 0)); // prototype 2206 __ lw(scratch, MemOperand(sp, 0)); // prototype
2229 } 2207 }
2230 __ push(scratch); 2208 PushOperand(scratch);
2231 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2209 EmitPropertyKey(property, lit->GetIdForProperty(i));
2232 2210
2233 // The static prototype property is read only. We handle the non computed 2211 // The static prototype property is read only. We handle the non computed
2234 // property name case in the parser. Since this is the only case where we 2212 // property name case in the parser. Since this is the only case where we
2235 // need to check for an own read only property we special case this so we do 2213 // need to check for an own read only property we special case this so we do
2236 // not need to do this for every property. 2214 // not need to do this for every property.
2237 if (property->is_static() && property->is_computed_name()) { 2215 if (property->is_static() && property->is_computed_name()) {
2238 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2216 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2239 __ push(v0); 2217 __ push(v0);
2240 } 2218 }
2241 2219
2242 VisitForStackValue(value); 2220 VisitForStackValue(value);
2243 if (NeedsHomeObject(value)) { 2221 if (NeedsHomeObject(value)) {
2244 EmitSetHomeObject(value, 2, property->GetSlot()); 2222 EmitSetHomeObject(value, 2, property->GetSlot());
2245 } 2223 }
2246 2224
2247 switch (property->kind()) { 2225 switch (property->kind()) {
2248 case ObjectLiteral::Property::CONSTANT: 2226 case ObjectLiteral::Property::CONSTANT:
2249 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2227 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2250 case ObjectLiteral::Property::PROTOTYPE: 2228 case ObjectLiteral::Property::PROTOTYPE:
2251 UNREACHABLE(); 2229 UNREACHABLE();
2252 case ObjectLiteral::Property::COMPUTED: 2230 case ObjectLiteral::Property::COMPUTED:
2253 __ Push(Smi::FromInt(DONT_ENUM)); 2231 PushOperand(Smi::FromInt(DONT_ENUM));
2254 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2232 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2255 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2233 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2256 break; 2234 break;
2257 2235
2258 case ObjectLiteral::Property::GETTER: 2236 case ObjectLiteral::Property::GETTER:
2259 __ Push(Smi::FromInt(DONT_ENUM)); 2237 PushOperand(Smi::FromInt(DONT_ENUM));
2260 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2238 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2261 break; 2239 break;
2262 2240
2263 case ObjectLiteral::Property::SETTER: 2241 case ObjectLiteral::Property::SETTER:
2264 __ Push(Smi::FromInt(DONT_ENUM)); 2242 PushOperand(Smi::FromInt(DONT_ENUM));
2265 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2243 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2266 break; 2244 break;
2267 2245
2268 default: 2246 default:
2269 UNREACHABLE(); 2247 UNREACHABLE();
2270 } 2248 }
2271 } 2249 }
2272 } 2250 }
2273 2251
2274 2252
2275 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2253 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2276 __ mov(a0, result_register()); 2254 __ mov(a0, result_register());
2277 __ pop(a1); 2255 PopOperand(a1);
2278 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2256 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2279 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2257 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2280 CallIC(code, expr->BinaryOperationFeedbackId()); 2258 CallIC(code, expr->BinaryOperationFeedbackId());
2281 patch_site.EmitPatchInfo(); 2259 patch_site.EmitPatchInfo();
2282 context()->Plug(v0); 2260 context()->Plug(v0);
2283 } 2261 }
2284 2262
2285 2263
2286 void FullCodeGenerator::EmitAssignment(Expression* expr, 2264 void FullCodeGenerator::EmitAssignment(Expression* expr,
2287 FeedbackVectorSlot slot) { 2265 FeedbackVectorSlot slot) {
2288 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2266 DCHECK(expr->IsValidReferenceExpressionOrThis());
2289 2267
2290 Property* prop = expr->AsProperty(); 2268 Property* prop = expr->AsProperty();
2291 LhsKind assign_type = Property::GetAssignType(prop); 2269 LhsKind assign_type = Property::GetAssignType(prop);
2292 2270
2293 switch (assign_type) { 2271 switch (assign_type) {
2294 case VARIABLE: { 2272 case VARIABLE: {
2295 Variable* var = expr->AsVariableProxy()->var(); 2273 Variable* var = expr->AsVariableProxy()->var();
2296 EffectContext context(this); 2274 EffectContext context(this);
2297 EmitVariableAssignment(var, Token::ASSIGN, slot); 2275 EmitVariableAssignment(var, Token::ASSIGN, slot);
2298 break; 2276 break;
2299 } 2277 }
2300 case NAMED_PROPERTY: { 2278 case NAMED_PROPERTY: {
2301 __ push(result_register()); // Preserve value. 2279 PushOperand(result_register()); // Preserve value.
2302 VisitForAccumulatorValue(prop->obj()); 2280 VisitForAccumulatorValue(prop->obj());
2303 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); 2281 __ mov(StoreDescriptor::ReceiverRegister(), result_register());
2304 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2282 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2305 __ li(StoreDescriptor::NameRegister(), 2283 __ li(StoreDescriptor::NameRegister(),
2306 Operand(prop->key()->AsLiteral()->value())); 2284 Operand(prop->key()->AsLiteral()->value()));
2307 EmitLoadStoreICSlot(slot); 2285 EmitLoadStoreICSlot(slot);
2308 CallStoreIC(); 2286 CallStoreIC();
2309 break; 2287 break;
2310 } 2288 }
2311 case NAMED_SUPER_PROPERTY: { 2289 case NAMED_SUPER_PROPERTY: {
2312 __ Push(v0); 2290 PushOperand(v0);
2313 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2291 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2314 VisitForAccumulatorValue( 2292 VisitForAccumulatorValue(
2315 prop->obj()->AsSuperPropertyReference()->home_object()); 2293 prop->obj()->AsSuperPropertyReference()->home_object());
2316 // stack: value, this; v0: home_object 2294 // stack: value, this; v0: home_object
2317 Register scratch = a2; 2295 Register scratch = a2;
2318 Register scratch2 = a3; 2296 Register scratch2 = a3;
2319 __ mov(scratch, result_register()); // home_object 2297 __ mov(scratch, result_register()); // home_object
2320 __ lw(v0, MemOperand(sp, kPointerSize)); // value 2298 __ lw(v0, MemOperand(sp, kPointerSize)); // value
2321 __ lw(scratch2, MemOperand(sp, 0)); // this 2299 __ lw(scratch2, MemOperand(sp, 0)); // this
2322 __ sw(scratch2, MemOperand(sp, kPointerSize)); // this 2300 __ sw(scratch2, MemOperand(sp, kPointerSize)); // this
2323 __ sw(scratch, MemOperand(sp, 0)); // home_object 2301 __ sw(scratch, MemOperand(sp, 0)); // home_object
2324 // stack: this, home_object; v0: value 2302 // stack: this, home_object; v0: value
2325 EmitNamedSuperPropertyStore(prop); 2303 EmitNamedSuperPropertyStore(prop);
2326 break; 2304 break;
2327 } 2305 }
2328 case KEYED_SUPER_PROPERTY: { 2306 case KEYED_SUPER_PROPERTY: {
2329 __ Push(v0); 2307 PushOperand(v0);
2330 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2308 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2331 VisitForStackValue( 2309 VisitForStackValue(
2332 prop->obj()->AsSuperPropertyReference()->home_object()); 2310 prop->obj()->AsSuperPropertyReference()->home_object());
2333 VisitForAccumulatorValue(prop->key()); 2311 VisitForAccumulatorValue(prop->key());
2334 Register scratch = a2; 2312 Register scratch = a2;
2335 Register scratch2 = a3; 2313 Register scratch2 = a3;
2336 __ lw(scratch2, MemOperand(sp, 2 * kPointerSize)); // value 2314 __ lw(scratch2, MemOperand(sp, 2 * kPointerSize)); // value
2337 // stack: value, this, home_object; v0: key, a3: value 2315 // stack: value, this, home_object; v0: key, a3: value
2338 __ lw(scratch, MemOperand(sp, kPointerSize)); // this 2316 __ lw(scratch, MemOperand(sp, kPointerSize)); // this
2339 __ sw(scratch, MemOperand(sp, 2 * kPointerSize)); 2317 __ sw(scratch, MemOperand(sp, 2 * kPointerSize));
2340 __ lw(scratch, MemOperand(sp, 0)); // home_object 2318 __ lw(scratch, MemOperand(sp, 0)); // home_object
2341 __ sw(scratch, MemOperand(sp, kPointerSize)); 2319 __ sw(scratch, MemOperand(sp, kPointerSize));
2342 __ sw(v0, MemOperand(sp, 0)); 2320 __ sw(v0, MemOperand(sp, 0));
2343 __ Move(v0, scratch2); 2321 __ Move(v0, scratch2);
2344 // stack: this, home_object, key; v0: value. 2322 // stack: this, home_object, key; v0: value.
2345 EmitKeyedSuperPropertyStore(prop); 2323 EmitKeyedSuperPropertyStore(prop);
2346 break; 2324 break;
2347 } 2325 }
2348 case KEYED_PROPERTY: { 2326 case KEYED_PROPERTY: {
2349 __ push(result_register()); // Preserve value. 2327 PushOperand(result_register()); // Preserve value.
2350 VisitForStackValue(prop->obj()); 2328 VisitForStackValue(prop->obj());
2351 VisitForAccumulatorValue(prop->key()); 2329 VisitForAccumulatorValue(prop->key());
2352 __ mov(StoreDescriptor::NameRegister(), result_register()); 2330 __ mov(StoreDescriptor::NameRegister(), result_register());
2353 __ Pop(StoreDescriptor::ValueRegister(), 2331 PopOperands(StoreDescriptor::ValueRegister(),
2354 StoreDescriptor::ReceiverRegister()); 2332 StoreDescriptor::ReceiverRegister());
2355 EmitLoadStoreICSlot(slot); 2333 EmitLoadStoreICSlot(slot);
2356 Handle<Code> ic = 2334 Handle<Code> ic =
2357 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2335 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2358 CallIC(ic); 2336 CallIC(ic);
2359 break; 2337 break;
2360 } 2338 }
2361 } 2339 }
2362 context()->Plug(v0); 2340 context()->Plug(v0);
2363 } 2341 }
2364 2342
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 2462
2485 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2463 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2486 // Assignment to a property, using a named store IC. 2464 // Assignment to a property, using a named store IC.
2487 Property* prop = expr->target()->AsProperty(); 2465 Property* prop = expr->target()->AsProperty();
2488 DCHECK(prop != NULL); 2466 DCHECK(prop != NULL);
2489 DCHECK(prop->key()->IsLiteral()); 2467 DCHECK(prop->key()->IsLiteral());
2490 2468
2491 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2469 __ mov(StoreDescriptor::ValueRegister(), result_register());
2492 __ li(StoreDescriptor::NameRegister(), 2470 __ li(StoreDescriptor::NameRegister(),
2493 Operand(prop->key()->AsLiteral()->value())); 2471 Operand(prop->key()->AsLiteral()->value()));
2494 __ pop(StoreDescriptor::ReceiverRegister()); 2472 PopOperand(StoreDescriptor::ReceiverRegister());
2495 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2473 EmitLoadStoreICSlot(expr->AssignmentSlot());
2496 CallStoreIC(); 2474 CallStoreIC();
2497 2475
2498 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2476 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2499 context()->Plug(v0); 2477 context()->Plug(v0);
2500 } 2478 }
2501 2479
2502 2480
2503 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2481 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2504 // Assignment to named property of super. 2482 // Assignment to named property of super.
2505 // v0 : value 2483 // v0 : value
2506 // stack : receiver ('this'), home_object 2484 // stack : receiver ('this'), home_object
2507 DCHECK(prop != NULL); 2485 DCHECK(prop != NULL);
2508 Literal* key = prop->key()->AsLiteral(); 2486 Literal* key = prop->key()->AsLiteral();
2509 DCHECK(key != NULL); 2487 DCHECK(key != NULL);
2510 2488
2511 __ Push(key->value()); 2489 PushOperand(key->value());
2512 __ Push(v0); 2490 PushOperand(v0);
2513 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2491 CallRuntimeWithOperands(is_strict(language_mode())
2514 : Runtime::kStoreToSuper_Sloppy)); 2492 ? Runtime::kStoreToSuper_Strict
2493 : Runtime::kStoreToSuper_Sloppy);
2515 } 2494 }
2516 2495
2517 2496
2518 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2497 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2519 // Assignment to named property of super. 2498 // Assignment to named property of super.
2520 // v0 : value 2499 // v0 : value
2521 // stack : receiver ('this'), home_object, key 2500 // stack : receiver ('this'), home_object, key
2522 DCHECK(prop != NULL); 2501 DCHECK(prop != NULL);
2523 2502
2524 __ Push(v0); 2503 PushOperand(v0);
2525 __ CallRuntime((is_strict(language_mode()) 2504 CallRuntimeWithOperands(is_strict(language_mode())
2526 ? Runtime::kStoreKeyedToSuper_Strict 2505 ? Runtime::kStoreKeyedToSuper_Strict
2527 : Runtime::kStoreKeyedToSuper_Sloppy)); 2506 : Runtime::kStoreKeyedToSuper_Sloppy);
2528 } 2507 }
2529 2508
2530 2509
2531 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2510 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2532 // Assignment to a property, using a keyed store IC. 2511 // Assignment to a property, using a keyed store IC.
2533 // Call keyed store IC. 2512 // Call keyed store IC.
2534 // The arguments are: 2513 // The arguments are:
2535 // - a0 is the value, 2514 // - a0 is the value,
2536 // - a1 is the key, 2515 // - a1 is the key,
2537 // - a2 is the receiver. 2516 // - a2 is the receiver.
2538 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2517 __ mov(StoreDescriptor::ValueRegister(), result_register());
2539 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2518 PopOperands(StoreDescriptor::ReceiverRegister(),
2519 StoreDescriptor::NameRegister());
2540 DCHECK(StoreDescriptor::ValueRegister().is(a0)); 2520 DCHECK(StoreDescriptor::ValueRegister().is(a0));
2541 2521
2542 Handle<Code> ic = 2522 Handle<Code> ic =
2543 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2523 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2544 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2524 EmitLoadStoreICSlot(expr->AssignmentSlot());
2545 CallIC(ic); 2525 CallIC(ic);
2546 2526
2547 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2527 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2548 context()->Plug(v0); 2528 context()->Plug(v0);
2549 } 2529 }
(...skipping 14 matching lines...) Expand all
2564 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2544 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2565 VisitForStackValue( 2545 VisitForStackValue(
2566 expr->obj()->AsSuperPropertyReference()->home_object()); 2546 expr->obj()->AsSuperPropertyReference()->home_object());
2567 EmitNamedSuperPropertyLoad(expr); 2547 EmitNamedSuperPropertyLoad(expr);
2568 } 2548 }
2569 } else { 2549 } else {
2570 if (!expr->IsSuperAccess()) { 2550 if (!expr->IsSuperAccess()) {
2571 VisitForStackValue(expr->obj()); 2551 VisitForStackValue(expr->obj());
2572 VisitForAccumulatorValue(expr->key()); 2552 VisitForAccumulatorValue(expr->key());
2573 __ Move(LoadDescriptor::NameRegister(), v0); 2553 __ Move(LoadDescriptor::NameRegister(), v0);
2574 __ pop(LoadDescriptor::ReceiverRegister()); 2554 PopOperand(LoadDescriptor::ReceiverRegister());
2575 EmitKeyedPropertyLoad(expr); 2555 EmitKeyedPropertyLoad(expr);
2576 } else { 2556 } else {
2577 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2557 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2578 VisitForStackValue( 2558 VisitForStackValue(
2579 expr->obj()->AsSuperPropertyReference()->home_object()); 2559 expr->obj()->AsSuperPropertyReference()->home_object());
2580 VisitForStackValue(expr->key()); 2560 VisitForStackValue(expr->key());
2581 EmitKeyedSuperPropertyLoad(expr); 2561 EmitKeyedSuperPropertyLoad(expr);
2582 } 2562 }
2583 } 2563 }
2584 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2564 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
(...skipping 15 matching lines...) Expand all
2600 // Get the target function. 2580 // Get the target function.
2601 ConvertReceiverMode convert_mode; 2581 ConvertReceiverMode convert_mode;
2602 if (callee->IsVariableProxy()) { 2582 if (callee->IsVariableProxy()) {
2603 { StackValueContext context(this); 2583 { StackValueContext context(this);
2604 EmitVariableLoad(callee->AsVariableProxy()); 2584 EmitVariableLoad(callee->AsVariableProxy());
2605 PrepareForBailout(callee, NO_REGISTERS); 2585 PrepareForBailout(callee, NO_REGISTERS);
2606 } 2586 }
2607 // Push undefined as receiver. This is patched in the method prologue if it 2587 // Push undefined as receiver. This is patched in the method prologue if it
2608 // is a sloppy mode method. 2588 // is a sloppy mode method.
2609 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 2589 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2610 __ push(at); 2590 PushOperand(at);
2611 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2591 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2612 } else { 2592 } else {
2613 // Load the function from the receiver. 2593 // Load the function from the receiver.
2614 DCHECK(callee->IsProperty()); 2594 DCHECK(callee->IsProperty());
2615 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2595 DCHECK(!callee->AsProperty()->IsSuperAccess());
2616 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2596 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2617 EmitNamedPropertyLoad(callee->AsProperty()); 2597 EmitNamedPropertyLoad(callee->AsProperty());
2618 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2598 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2619 // Push the target function under the receiver. 2599 // Push the target function under the receiver.
2620 __ lw(at, MemOperand(sp, 0)); 2600 __ lw(at, MemOperand(sp, 0));
2621 __ push(at); 2601 PushOperand(at);
2622 __ sw(v0, MemOperand(sp, kPointerSize)); 2602 __ sw(v0, MemOperand(sp, kPointerSize));
2623 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2603 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2624 } 2604 }
2625 2605
2626 EmitCall(expr, convert_mode); 2606 EmitCall(expr, convert_mode);
2627 } 2607 }
2628 2608
2629 2609
2630 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2610 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2631 SetExpressionPosition(expr); 2611 SetExpressionPosition(expr);
2632 Expression* callee = expr->expression(); 2612 Expression* callee = expr->expression();
2633 DCHECK(callee->IsProperty()); 2613 DCHECK(callee->IsProperty());
2634 Property* prop = callee->AsProperty(); 2614 Property* prop = callee->AsProperty();
2635 DCHECK(prop->IsSuperAccess()); 2615 DCHECK(prop->IsSuperAccess());
2636 2616
2637 Literal* key = prop->key()->AsLiteral(); 2617 Literal* key = prop->key()->AsLiteral();
2638 DCHECK(!key->value()->IsSmi()); 2618 DCHECK(!key->value()->IsSmi());
2639 // Load the function from the receiver. 2619 // Load the function from the receiver.
2640 const Register scratch = a1; 2620 const Register scratch = a1;
2641 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2621 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2642 VisitForAccumulatorValue(super_ref->home_object()); 2622 VisitForAccumulatorValue(super_ref->home_object());
2643 __ mov(scratch, v0); 2623 __ mov(scratch, v0);
2644 VisitForAccumulatorValue(super_ref->this_var()); 2624 VisitForAccumulatorValue(super_ref->this_var());
2645 __ Push(scratch, v0, v0, scratch); 2625 PushOperands(scratch, v0, v0, scratch);
2646 __ Push(key->value()); 2626 PushOperand(key->value());
2647 2627
2648 // Stack here: 2628 // Stack here:
2649 // - home_object 2629 // - home_object
2650 // - this (receiver) 2630 // - this (receiver)
2651 // - this (receiver) <-- LoadFromSuper will pop here and below. 2631 // - this (receiver) <-- LoadFromSuper will pop here and below.
2652 // - home_object 2632 // - home_object
2653 // - key 2633 // - key
2654 __ CallRuntime(Runtime::kLoadFromSuper); 2634 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2655 2635
2656 // Replace home_object with target function. 2636 // Replace home_object with target function.
2657 __ sw(v0, MemOperand(sp, kPointerSize)); 2637 __ sw(v0, MemOperand(sp, kPointerSize));
2658 2638
2659 // Stack here: 2639 // Stack here:
2660 // - target function 2640 // - target function
2661 // - this (receiver) 2641 // - this (receiver)
2662 EmitCall(expr); 2642 EmitCall(expr);
2663 } 2643 }
2664 2644
2665 2645
2666 // Code common for calls using the IC. 2646 // Code common for calls using the IC.
2667 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2647 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2668 Expression* key) { 2648 Expression* key) {
2669 // Load the key. 2649 // Load the key.
2670 VisitForAccumulatorValue(key); 2650 VisitForAccumulatorValue(key);
2671 2651
2672 Expression* callee = expr->expression(); 2652 Expression* callee = expr->expression();
2673 2653
2674 // Load the function from the receiver. 2654 // Load the function from the receiver.
2675 DCHECK(callee->IsProperty()); 2655 DCHECK(callee->IsProperty());
2676 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2656 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2677 __ Move(LoadDescriptor::NameRegister(), v0); 2657 __ Move(LoadDescriptor::NameRegister(), v0);
2678 EmitKeyedPropertyLoad(callee->AsProperty()); 2658 EmitKeyedPropertyLoad(callee->AsProperty());
2679 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2659 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2680 2660
2681 // Push the target function under the receiver. 2661 // Push the target function under the receiver.
2682 __ lw(at, MemOperand(sp, 0)); 2662 __ lw(at, MemOperand(sp, 0));
2683 __ push(at); 2663 PushOperand(at);
2684 __ sw(v0, MemOperand(sp, kPointerSize)); 2664 __ sw(v0, MemOperand(sp, kPointerSize));
2685 2665
2686 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2666 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2687 } 2667 }
2688 2668
2689 2669
2690 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2670 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2691 Expression* callee = expr->expression(); 2671 Expression* callee = expr->expression();
2692 DCHECK(callee->IsProperty()); 2672 DCHECK(callee->IsProperty());
2693 Property* prop = callee->AsProperty(); 2673 Property* prop = callee->AsProperty();
2694 DCHECK(prop->IsSuperAccess()); 2674 DCHECK(prop->IsSuperAccess());
2695 2675
2696 SetExpressionPosition(prop); 2676 SetExpressionPosition(prop);
2697 // Load the function from the receiver. 2677 // Load the function from the receiver.
2698 const Register scratch = a1; 2678 const Register scratch = a1;
2699 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2679 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2700 VisitForAccumulatorValue(super_ref->home_object()); 2680 VisitForAccumulatorValue(super_ref->home_object());
2701 __ Move(scratch, v0); 2681 __ Move(scratch, v0);
2702 VisitForAccumulatorValue(super_ref->this_var()); 2682 VisitForAccumulatorValue(super_ref->this_var());
2703 __ Push(scratch, v0, v0, scratch); 2683 PushOperands(scratch, v0, v0, scratch);
2704 VisitForStackValue(prop->key()); 2684 VisitForStackValue(prop->key());
2705 2685
2706 // Stack here: 2686 // Stack here:
2707 // - home_object 2687 // - home_object
2708 // - this (receiver) 2688 // - this (receiver)
2709 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2689 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2710 // - home_object 2690 // - home_object
2711 // - key 2691 // - key
2712 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2692 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2713 2693
2714 // Replace home_object with target function. 2694 // Replace home_object with target function.
2715 __ sw(v0, MemOperand(sp, kPointerSize)); 2695 __ sw(v0, MemOperand(sp, kPointerSize));
2716 2696
2717 // Stack here: 2697 // Stack here:
2718 // - target function 2698 // - target function
2719 // - this (receiver) 2699 // - this (receiver)
2720 EmitCall(expr); 2700 EmitCall(expr);
2721 } 2701 }
2722 2702
(...skipping 18 matching lines...) Expand all
2741 EmitProfilingCounterHandlingForReturnSequence(true); 2721 EmitProfilingCounterHandlingForReturnSequence(true);
2742 } 2722 }
2743 Handle<Code> ic = 2723 Handle<Code> ic =
2744 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2724 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2745 .code(); 2725 .code();
2746 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); 2726 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
2747 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2727 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2748 // Don't assign a type feedback id to the IC, since type feedback is provided 2728 // Don't assign a type feedback id to the IC, since type feedback is provided
2749 // by the vector above. 2729 // by the vector above.
2750 CallIC(ic); 2730 CallIC(ic);
2731 OperandStackDepthDecrement(arg_count + 1);
2751 2732
2752 RecordJSReturnSite(expr); 2733 RecordJSReturnSite(expr);
2753 // Restore context register. 2734 // Restore context register.
2754 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2735 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2755 context()->DropAndPlug(1, v0); 2736 context()->DropAndPlug(1, v0);
2756 } 2737 }
2757 2738
2758 2739
2759 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2740 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2760 // t3: copy of the first argument or undefined if it doesn't exist. 2741 // t3: copy of the first argument or undefined if it doesn't exist.
(...skipping 27 matching lines...) Expand all
2788 SetExpressionPosition(callee); 2769 SetExpressionPosition(callee);
2789 // Generate code for loading from variables potentially shadowed by 2770 // Generate code for loading from variables potentially shadowed by
2790 // eval-introduced variables. 2771 // eval-introduced variables.
2791 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2772 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2792 2773
2793 __ bind(&slow); 2774 __ bind(&slow);
2794 // Call the runtime to find the function to call (returned in v0) 2775 // Call the runtime to find the function to call (returned in v0)
2795 // and the object holding it (returned in v1). 2776 // and the object holding it (returned in v1).
2796 __ Push(callee->name()); 2777 __ Push(callee->name());
2797 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2778 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2798 __ Push(v0, v1); // Function, receiver. 2779 PushOperands(v0, v1); // Function, receiver.
2799 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2780 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2800 2781
2801 // If fast case code has been generated, emit code to push the 2782 // If fast case code has been generated, emit code to push the
2802 // function and receiver and have the slow path jump around this 2783 // function and receiver and have the slow path jump around this
2803 // code. 2784 // code.
2804 if (done.is_linked()) { 2785 if (done.is_linked()) {
2805 Label call; 2786 Label call;
2806 __ Branch(&call); 2787 __ Branch(&call);
2807 __ bind(&done); 2788 __ bind(&done);
2808 // Push function. 2789 // Push function.
2809 __ push(v0); 2790 __ push(v0);
2810 // The receiver is implicitly the global receiver. Indicate this 2791 // The receiver is implicitly the global receiver. Indicate this
2811 // by passing the hole to the call function stub. 2792 // by passing the hole to the call function stub.
2812 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); 2793 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
2813 __ push(a1); 2794 __ push(a1);
2814 __ bind(&call); 2795 __ bind(&call);
2815 } 2796 }
2816 } else { 2797 } else {
2817 VisitForStackValue(callee); 2798 VisitForStackValue(callee);
2818 // refEnv.WithBaseObject() 2799 // refEnv.WithBaseObject()
2819 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 2800 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
2820 __ push(a2); // Reserved receiver slot. 2801 PushOperand(a2); // Reserved receiver slot.
2821 } 2802 }
2822 } 2803 }
2823 2804
2824 2805
2825 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2806 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2826 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2807 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2827 // to resolve the function we need to call. Then we call the resolved 2808 // to resolve the function we need to call. Then we call the resolved
2828 // function using the given arguments. 2809 // function using the given arguments.
2829 ZoneList<Expression*>* args = expr->arguments(); 2810 ZoneList<Expression*>* args = expr->arguments();
2830 int arg_count = args->length(); 2811 int arg_count = args->length();
(...skipping 14 matching lines...) Expand all
2845 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2826 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2846 2827
2847 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2828 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2848 // Record source position for debugger. 2829 // Record source position for debugger.
2849 SetCallPosition(expr); 2830 SetCallPosition(expr);
2850 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2831 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2851 __ li(a0, Operand(arg_count)); 2832 __ li(a0, Operand(arg_count));
2852 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2833 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2853 expr->tail_call_mode()), 2834 expr->tail_call_mode()),
2854 RelocInfo::CODE_TARGET); 2835 RelocInfo::CODE_TARGET);
2836 OperandStackDepthDecrement(arg_count + 1);
2855 RecordJSReturnSite(expr); 2837 RecordJSReturnSite(expr);
2856 // Restore context register. 2838 // Restore context register.
2857 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2839 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2858 context()->DropAndPlug(1, v0); 2840 context()->DropAndPlug(1, v0);
2859 } 2841 }
2860 2842
2861 2843
2862 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2844 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2863 Comment cmnt(masm_, "[ CallNew"); 2845 Comment cmnt(masm_, "[ CallNew");
2864 // According to ECMA-262, section 11.2.2, page 44, the function 2846 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2885 // Load function and argument count into a1 and a0. 2867 // Load function and argument count into a1 and a0.
2886 __ li(a0, Operand(arg_count)); 2868 __ li(a0, Operand(arg_count));
2887 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2869 __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
2888 2870
2889 // Record call targets in unoptimized code. 2871 // Record call targets in unoptimized code.
2890 __ EmitLoadTypeFeedbackVector(a2); 2872 __ EmitLoadTypeFeedbackVector(a2);
2891 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2873 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
2892 2874
2893 CallConstructStub stub(isolate()); 2875 CallConstructStub stub(isolate());
2894 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2876 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2877 OperandStackDepthDecrement(arg_count + 1);
2895 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2878 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2896 // Restore context register. 2879 // Restore context register.
2897 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2880 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2898 context()->Plug(v0); 2881 context()->Plug(v0);
2899 } 2882 }
2900 2883
2901 2884
2902 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2885 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2903 SuperCallReference* super_call_ref = 2886 SuperCallReference* super_call_ref =
2904 expr->expression()->AsSuperCallReference(); 2887 expr->expression()->AsSuperCallReference();
2905 DCHECK_NOT_NULL(super_call_ref); 2888 DCHECK_NOT_NULL(super_call_ref);
2906 2889
2907 // Push the super constructor target on the stack (may be null, 2890 // Push the super constructor target on the stack (may be null,
2908 // but the Construct builtin can deal with that properly). 2891 // but the Construct builtin can deal with that properly).
2909 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2892 VisitForAccumulatorValue(super_call_ref->this_function_var());
2910 __ AssertFunction(result_register()); 2893 __ AssertFunction(result_register());
2911 __ lw(result_register(), 2894 __ lw(result_register(),
2912 FieldMemOperand(result_register(), HeapObject::kMapOffset)); 2895 FieldMemOperand(result_register(), HeapObject::kMapOffset));
2913 __ lw(result_register(), 2896 __ lw(result_register(),
2914 FieldMemOperand(result_register(), Map::kPrototypeOffset)); 2897 FieldMemOperand(result_register(), Map::kPrototypeOffset));
2915 __ Push(result_register()); 2898 PushOperand(result_register());
2916 2899
2917 // Push the arguments ("left-to-right") on the stack. 2900 // Push the arguments ("left-to-right") on the stack.
2918 ZoneList<Expression*>* args = expr->arguments(); 2901 ZoneList<Expression*>* args = expr->arguments();
2919 int arg_count = args->length(); 2902 int arg_count = args->length();
2920 for (int i = 0; i < arg_count; i++) { 2903 for (int i = 0; i < arg_count; i++) {
2921 VisitForStackValue(args->at(i)); 2904 VisitForStackValue(args->at(i));
2922 } 2905 }
2923 2906
2924 // Call the construct call builtin that handles allocation and 2907 // Call the construct call builtin that handles allocation and
2925 // constructor invocation. 2908 // constructor invocation.
2926 SetConstructCallPosition(expr); 2909 SetConstructCallPosition(expr);
2927 2910
2928 // Load new target into a3. 2911 // Load new target into a3.
2929 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2912 VisitForAccumulatorValue(super_call_ref->new_target_var());
2930 __ mov(a3, result_register()); 2913 __ mov(a3, result_register());
2931 2914
2932 // Load function and argument count into a1 and a0. 2915 // Load function and argument count into a1 and a0.
2933 __ li(a0, Operand(arg_count)); 2916 __ li(a0, Operand(arg_count));
2934 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2917 __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
2935 2918
2936 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2919 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2920 OperandStackDepthDecrement(arg_count + 1);
2937 2921
2938 RecordJSReturnSite(expr); 2922 RecordJSReturnSite(expr);
2939 2923
2940 // Restore context register. 2924 // Restore context register.
2941 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2925 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2942 context()->Plug(v0); 2926 context()->Plug(v0);
2943 } 2927 }
2944 2928
2945 2929
2946 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2930 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
3149 ZoneList<Expression*>* args = expr->arguments(); 3133 ZoneList<Expression*>* args = expr->arguments();
3150 DCHECK_EQ(3, args->length()); 3134 DCHECK_EQ(3, args->length());
3151 3135
3152 Register string = v0; 3136 Register string = v0;
3153 Register index = a1; 3137 Register index = a1;
3154 Register value = a2; 3138 Register value = a2;
3155 3139
3156 VisitForStackValue(args->at(0)); // index 3140 VisitForStackValue(args->at(0)); // index
3157 VisitForStackValue(args->at(1)); // value 3141 VisitForStackValue(args->at(1)); // value
3158 VisitForAccumulatorValue(args->at(2)); // string 3142 VisitForAccumulatorValue(args->at(2)); // string
3159 __ Pop(index, value); 3143 PopOperands(index, value);
3160 3144
3161 if (FLAG_debug_code) { 3145 if (FLAG_debug_code) {
3162 __ SmiTst(value, at); 3146 __ SmiTst(value, at);
3163 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); 3147 __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
3164 __ SmiTst(index, at); 3148 __ SmiTst(index, at);
3165 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); 3149 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
3166 __ SmiUntag(index, index); 3150 __ SmiUntag(index, index);
3167 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3151 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3168 Register scratch = t5; 3152 Register scratch = t5;
3169 __ EmitSeqStringSetCharCheck( 3153 __ EmitSeqStringSetCharCheck(
(...skipping 16 matching lines...) Expand all
3186 ZoneList<Expression*>* args = expr->arguments(); 3170 ZoneList<Expression*>* args = expr->arguments();
3187 DCHECK_EQ(3, args->length()); 3171 DCHECK_EQ(3, args->length());
3188 3172
3189 Register string = v0; 3173 Register string = v0;
3190 Register index = a1; 3174 Register index = a1;
3191 Register value = a2; 3175 Register value = a2;
3192 3176
3193 VisitForStackValue(args->at(0)); // index 3177 VisitForStackValue(args->at(0)); // index
3194 VisitForStackValue(args->at(1)); // value 3178 VisitForStackValue(args->at(1)); // value
3195 VisitForAccumulatorValue(args->at(2)); // string 3179 VisitForAccumulatorValue(args->at(2)); // string
3196 __ Pop(index, value); 3180 PopOperands(index, value);
3197 3181
3198 if (FLAG_debug_code) { 3182 if (FLAG_debug_code) {
3199 __ SmiTst(value, at); 3183 __ SmiTst(value, at);
3200 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); 3184 __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
3201 __ SmiTst(index, at); 3185 __ SmiTst(index, at);
3202 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); 3186 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
3203 __ SmiUntag(index, index); 3187 __ SmiUntag(index, index);
3204 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3188 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3205 Register scratch = t5; 3189 Register scratch = t5;
3206 __ EmitSeqStringSetCharCheck( 3190 __ EmitSeqStringSetCharCheck(
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3260 DCHECK(args->length() == 2); 3244 DCHECK(args->length() == 2);
3261 3245
3262 VisitForStackValue(args->at(0)); 3246 VisitForStackValue(args->at(0));
3263 VisitForAccumulatorValue(args->at(1)); 3247 VisitForAccumulatorValue(args->at(1));
3264 __ mov(a0, result_register()); 3248 __ mov(a0, result_register());
3265 3249
3266 Register object = a1; 3250 Register object = a1;
3267 Register index = a0; 3251 Register index = a0;
3268 Register result = v0; 3252 Register result = v0;
3269 3253
3270 __ pop(object); 3254 PopOperand(object);
3271 3255
3272 Label need_conversion; 3256 Label need_conversion;
3273 Label index_out_of_range; 3257 Label index_out_of_range;
3274 Label done; 3258 Label done;
3275 StringCharCodeAtGenerator generator(object, 3259 StringCharCodeAtGenerator generator(object,
3276 index, 3260 index,
3277 result, 3261 result,
3278 &need_conversion, 3262 &need_conversion,
3279 &need_conversion, 3263 &need_conversion,
3280 &index_out_of_range, 3264 &index_out_of_range,
(...skipping 27 matching lines...) Expand all
3308 3292
3309 VisitForStackValue(args->at(0)); 3293 VisitForStackValue(args->at(0));
3310 VisitForAccumulatorValue(args->at(1)); 3294 VisitForAccumulatorValue(args->at(1));
3311 __ mov(a0, result_register()); 3295 __ mov(a0, result_register());
3312 3296
3313 Register object = a1; 3297 Register object = a1;
3314 Register index = a0; 3298 Register index = a0;
3315 Register scratch = a3; 3299 Register scratch = a3;
3316 Register result = v0; 3300 Register result = v0;
3317 3301
3318 __ pop(object); 3302 PopOperand(object);
3319 3303
3320 Label need_conversion; 3304 Label need_conversion;
3321 Label index_out_of_range; 3305 Label index_out_of_range;
3322 Label done; 3306 Label done;
3323 StringCharAtGenerator generator(object, 3307 StringCharAtGenerator generator(object,
3324 index, 3308 index,
3325 scratch, 3309 scratch,
3326 result, 3310 result,
3327 &need_conversion, 3311 &need_conversion,
3328 &need_conversion, 3312 &need_conversion,
(...skipping 29 matching lines...) Expand all
3358 for (Expression* const arg : *args) { 3342 for (Expression* const arg : *args) {
3359 VisitForStackValue(arg); 3343 VisitForStackValue(arg);
3360 } 3344 }
3361 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3345 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3362 // Move target to a1. 3346 // Move target to a1.
3363 int const argc = args->length() - 2; 3347 int const argc = args->length() - 2;
3364 __ lw(a1, MemOperand(sp, (argc + 1) * kPointerSize)); 3348 __ lw(a1, MemOperand(sp, (argc + 1) * kPointerSize));
3365 // Call the target. 3349 // Call the target.
3366 __ li(a0, Operand(argc)); 3350 __ li(a0, Operand(argc));
3367 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3351 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3352 OperandStackDepthDecrement(argc + 1);
3368 // Restore context register. 3353 // Restore context register.
3369 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3354 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3370 // Discard the function left on TOS. 3355 // Discard the function left on TOS.
3371 context()->DropAndPlug(1, v0); 3356 context()->DropAndPlug(1, v0);
3372 } 3357 }
3373 3358
3374 3359
3375 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3360 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3376 ZoneList<Expression*>* args = expr->arguments(); 3361 ZoneList<Expression*>* args = expr->arguments();
3377 VisitForAccumulatorValue(args->at(0)); 3362 VisitForAccumulatorValue(args->at(0));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3443 __ LoadRoot(t0, Heap::kEmptyFixedArrayRootIndex); 3428 __ LoadRoot(t0, Heap::kEmptyFixedArrayRootIndex);
3444 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 3429 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
3445 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 3430 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset));
3446 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset)); 3431 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
3447 __ sw(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); 3432 __ sw(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset));
3448 __ sw(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); 3433 __ sw(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset));
3449 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3434 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3450 __ jmp(&done); 3435 __ jmp(&done);
3451 3436
3452 __ bind(&runtime); 3437 __ bind(&runtime);
3453 __ CallRuntime(Runtime::kCreateIterResultObject); 3438 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3454 3439
3455 __ bind(&done); 3440 __ bind(&done);
3456 context()->Plug(v0); 3441 context()->Plug(v0);
3457 } 3442 }
3458 3443
3459 3444
3460 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3445 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3461 // Push undefined as the receiver. 3446 // Push undefined as the receiver.
3462 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 3447 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
3463 __ push(v0); 3448 PushOperand(v0);
3464 3449
3465 __ LoadNativeContextSlot(expr->context_index(), v0); 3450 __ LoadNativeContextSlot(expr->context_index(), v0);
3466 } 3451 }
3467 3452
3468 3453
3469 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3454 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3470 ZoneList<Expression*>* args = expr->arguments(); 3455 ZoneList<Expression*>* args = expr->arguments();
3471 int arg_count = args->length(); 3456 int arg_count = args->length();
3472 3457
3473 SetCallPosition(expr); 3458 SetCallPosition(expr);
3474 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 3459 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
3475 __ li(a0, Operand(arg_count)); 3460 __ li(a0, Operand(arg_count));
3476 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3461 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3477 RelocInfo::CODE_TARGET); 3462 RelocInfo::CODE_TARGET);
3463 OperandStackDepthDecrement(arg_count + 1);
3478 } 3464 }
3479 3465
3480 3466
3481 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3467 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3482 ZoneList<Expression*>* args = expr->arguments(); 3468 ZoneList<Expression*>* args = expr->arguments();
3483 int arg_count = args->length(); 3469 int arg_count = args->length();
3484 3470
3485 if (expr->is_jsruntime()) { 3471 if (expr->is_jsruntime()) {
3486 Comment cmnt(masm_, "[ CallRuntime"); 3472 Comment cmnt(masm_, "[ CallRuntime");
3487 EmitLoadJSRuntimeFunction(expr); 3473 EmitLoadJSRuntimeFunction(expr);
3488 3474
3489 // Push the target function under the receiver. 3475 // Push the target function under the receiver.
3490 __ lw(at, MemOperand(sp, 0)); 3476 __ lw(at, MemOperand(sp, 0));
3491 __ push(at); 3477 PushOperand(at);
3492 __ sw(v0, MemOperand(sp, kPointerSize)); 3478 __ sw(v0, MemOperand(sp, kPointerSize));
3493 3479
3494 // Push the arguments ("left-to-right"). 3480 // Push the arguments ("left-to-right").
3495 for (int i = 0; i < arg_count; i++) { 3481 for (int i = 0; i < arg_count; i++) {
3496 VisitForStackValue(args->at(i)); 3482 VisitForStackValue(args->at(i));
3497 } 3483 }
3498 3484
3499 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3485 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3500 EmitCallJSRuntimeFunction(expr); 3486 EmitCallJSRuntimeFunction(expr);
3501 3487
(...skipping 15 matching lines...) Expand all
3517 default: { 3503 default: {
3518 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3504 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3519 // Push the arguments ("left-to-right"). 3505 // Push the arguments ("left-to-right").
3520 for (int i = 0; i < arg_count; i++) { 3506 for (int i = 0; i < arg_count; i++) {
3521 VisitForStackValue(args->at(i)); 3507 VisitForStackValue(args->at(i));
3522 } 3508 }
3523 3509
3524 // Call the C runtime function. 3510 // Call the C runtime function.
3525 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3511 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3526 __ CallRuntime(expr->function(), arg_count); 3512 __ CallRuntime(expr->function(), arg_count);
3513 OperandStackDepthDecrement(arg_count);
3527 context()->Plug(v0); 3514 context()->Plug(v0);
3528 } 3515 }
3529 } 3516 }
3530 } 3517 }
3531 } 3518 }
3532 3519
3533 3520
3534 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3521 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3535 switch (expr->op()) { 3522 switch (expr->op()) {
3536 case Token::DELETE: { 3523 case Token::DELETE: {
3537 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3524 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3538 Property* property = expr->expression()->AsProperty(); 3525 Property* property = expr->expression()->AsProperty();
3539 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3526 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3540 3527
3541 if (property != NULL) { 3528 if (property != NULL) {
3542 VisitForStackValue(property->obj()); 3529 VisitForStackValue(property->obj());
3543 VisitForStackValue(property->key()); 3530 VisitForStackValue(property->key());
3544 __ CallRuntime(is_strict(language_mode()) 3531 CallRuntimeWithOperands(is_strict(language_mode())
3545 ? Runtime::kDeleteProperty_Strict 3532 ? Runtime::kDeleteProperty_Strict
3546 : Runtime::kDeleteProperty_Sloppy); 3533 : Runtime::kDeleteProperty_Sloppy);
3547 context()->Plug(v0); 3534 context()->Plug(v0);
3548 } else if (proxy != NULL) { 3535 } else if (proxy != NULL) {
3549 Variable* var = proxy->var(); 3536 Variable* var = proxy->var();
3550 // Delete of an unqualified identifier is disallowed in strict mode but 3537 // Delete of an unqualified identifier is disallowed in strict mode but
3551 // "delete this" is allowed. 3538 // "delete this" is allowed.
3552 bool is_this = var->HasThisName(isolate()); 3539 bool is_this = var->HasThisName(isolate());
3553 DCHECK(is_sloppy(language_mode()) || is_this); 3540 DCHECK(is_sloppy(language_mode()) || is_this);
3554 if (var->IsUnallocatedOrGlobalSlot()) { 3541 if (var->IsUnallocatedOrGlobalSlot()) {
3555 __ LoadGlobalObject(a2); 3542 __ LoadGlobalObject(a2);
3556 __ li(a1, Operand(var->name())); 3543 __ li(a1, Operand(var->name()));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3602 // We handle value contexts explicitly rather than simply visiting 3589 // We handle value contexts explicitly rather than simply visiting
3603 // for control and plugging the control flow into the context, 3590 // for control and plugging the control flow into the context,
3604 // because we need to prepare a pair of extra administrative AST ids 3591 // because we need to prepare a pair of extra administrative AST ids
3605 // for the optimizing compiler. 3592 // for the optimizing compiler.
3606 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3593 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3607 Label materialize_true, materialize_false, done; 3594 Label materialize_true, materialize_false, done;
3608 VisitForControl(expr->expression(), 3595 VisitForControl(expr->expression(),
3609 &materialize_false, 3596 &materialize_false,
3610 &materialize_true, 3597 &materialize_true,
3611 &materialize_true); 3598 &materialize_true);
3599 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3612 __ bind(&materialize_true); 3600 __ bind(&materialize_true);
3613 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3601 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3614 __ LoadRoot(v0, Heap::kTrueValueRootIndex); 3602 __ LoadRoot(v0, Heap::kTrueValueRootIndex);
3615 if (context()->IsStackValue()) __ push(v0); 3603 if (context()->IsStackValue()) __ push(v0);
3616 __ jmp(&done); 3604 __ jmp(&done);
3617 __ bind(&materialize_false); 3605 __ bind(&materialize_false);
3618 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3606 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
3619 __ LoadRoot(v0, Heap::kFalseValueRootIndex); 3607 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
3620 if (context()->IsStackValue()) __ push(v0); 3608 if (context()->IsStackValue()) __ push(v0);
3621 __ bind(&done); 3609 __ bind(&done);
(...skipping 30 matching lines...) Expand all
3652 3640
3653 // Evaluate expression and get value. 3641 // Evaluate expression and get value.
3654 if (assign_type == VARIABLE) { 3642 if (assign_type == VARIABLE) {
3655 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3643 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3656 AccumulatorValueContext context(this); 3644 AccumulatorValueContext context(this);
3657 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3645 EmitVariableLoad(expr->expression()->AsVariableProxy());
3658 } else { 3646 } else {
3659 // Reserve space for result of postfix operation. 3647 // Reserve space for result of postfix operation.
3660 if (expr->is_postfix() && !context()->IsEffect()) { 3648 if (expr->is_postfix() && !context()->IsEffect()) {
3661 __ li(at, Operand(Smi::FromInt(0))); 3649 __ li(at, Operand(Smi::FromInt(0)));
3662 __ push(at); 3650 PushOperand(at);
3663 } 3651 }
3664 switch (assign_type) { 3652 switch (assign_type) {
3665 case NAMED_PROPERTY: { 3653 case NAMED_PROPERTY: {
3666 // Put the object both on the stack and in the register. 3654 // Put the object both on the stack and in the register.
3667 VisitForStackValue(prop->obj()); 3655 VisitForStackValue(prop->obj());
3668 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 3656 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
3669 EmitNamedPropertyLoad(prop); 3657 EmitNamedPropertyLoad(prop);
3670 break; 3658 break;
3671 } 3659 }
3672 3660
3673 case NAMED_SUPER_PROPERTY: { 3661 case NAMED_SUPER_PROPERTY: {
3674 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3662 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3675 VisitForAccumulatorValue( 3663 VisitForAccumulatorValue(
3676 prop->obj()->AsSuperPropertyReference()->home_object()); 3664 prop->obj()->AsSuperPropertyReference()->home_object());
3677 __ Push(result_register()); 3665 PushOperand(result_register());
3678 const Register scratch = a1; 3666 const Register scratch = a1;
3679 __ lw(scratch, MemOperand(sp, kPointerSize)); 3667 __ lw(scratch, MemOperand(sp, kPointerSize));
3680 __ Push(scratch, result_register()); 3668 PushOperands(scratch, result_register());
3681 EmitNamedSuperPropertyLoad(prop); 3669 EmitNamedSuperPropertyLoad(prop);
3682 break; 3670 break;
3683 } 3671 }
3684 3672
3685 case KEYED_SUPER_PROPERTY: { 3673 case KEYED_SUPER_PROPERTY: {
3686 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3674 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3687 VisitForAccumulatorValue( 3675 VisitForAccumulatorValue(
3688 prop->obj()->AsSuperPropertyReference()->home_object()); 3676 prop->obj()->AsSuperPropertyReference()->home_object());
3689 const Register scratch = a1; 3677 const Register scratch = a1;
3690 const Register scratch1 = t0; 3678 const Register scratch1 = t0;
3691 __ Move(scratch, result_register()); 3679 __ Move(scratch, result_register());
3692 VisitForAccumulatorValue(prop->key()); 3680 VisitForAccumulatorValue(prop->key());
3693 __ Push(scratch, result_register()); 3681 PushOperands(scratch, result_register());
3694 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize)); 3682 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize));
3695 __ Push(scratch1, scratch, result_register()); 3683 PushOperands(scratch1, scratch, result_register());
3696 EmitKeyedSuperPropertyLoad(prop); 3684 EmitKeyedSuperPropertyLoad(prop);
3697 break; 3685 break;
3698 } 3686 }
3699 3687
3700 case KEYED_PROPERTY: { 3688 case KEYED_PROPERTY: {
3701 VisitForStackValue(prop->obj()); 3689 VisitForStackValue(prop->obj());
3702 VisitForStackValue(prop->key()); 3690 VisitForStackValue(prop->key());
3703 __ lw(LoadDescriptor::ReceiverRegister(), 3691 __ lw(LoadDescriptor::ReceiverRegister(),
3704 MemOperand(sp, 1 * kPointerSize)); 3692 MemOperand(sp, 1 * kPointerSize));
3705 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); 3693 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3771 } 3759 }
3772 3760
3773 // Save result for postfix expressions. 3761 // Save result for postfix expressions.
3774 if (expr->is_postfix()) { 3762 if (expr->is_postfix()) {
3775 if (!context()->IsEffect()) { 3763 if (!context()->IsEffect()) {
3776 // Save the result on the stack. If we have a named or keyed property 3764 // Save the result on the stack. If we have a named or keyed property
3777 // we store the result under the receiver that is currently on top 3765 // we store the result under the receiver that is currently on top
3778 // of the stack. 3766 // of the stack.
3779 switch (assign_type) { 3767 switch (assign_type) {
3780 case VARIABLE: 3768 case VARIABLE:
3781 __ push(v0); 3769 PushOperand(v0);
3782 break; 3770 break;
3783 case NAMED_PROPERTY: 3771 case NAMED_PROPERTY:
3784 __ sw(v0, MemOperand(sp, kPointerSize)); 3772 __ sw(v0, MemOperand(sp, kPointerSize));
3785 break; 3773 break;
3786 case NAMED_SUPER_PROPERTY: 3774 case NAMED_SUPER_PROPERTY:
3787 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); 3775 __ sw(v0, MemOperand(sp, 2 * kPointerSize));
3788 break; 3776 break;
3789 case KEYED_PROPERTY: 3777 case KEYED_PROPERTY:
3790 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); 3778 __ sw(v0, MemOperand(sp, 2 * kPointerSize));
3791 break; 3779 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3829 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3817 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3830 Token::ASSIGN, expr->CountSlot()); 3818 Token::ASSIGN, expr->CountSlot());
3831 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3819 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3832 context()->Plug(v0); 3820 context()->Plug(v0);
3833 } 3821 }
3834 break; 3822 break;
3835 case NAMED_PROPERTY: { 3823 case NAMED_PROPERTY: {
3836 __ mov(StoreDescriptor::ValueRegister(), result_register()); 3824 __ mov(StoreDescriptor::ValueRegister(), result_register());
3837 __ li(StoreDescriptor::NameRegister(), 3825 __ li(StoreDescriptor::NameRegister(),
3838 Operand(prop->key()->AsLiteral()->value())); 3826 Operand(prop->key()->AsLiteral()->value()));
3839 __ pop(StoreDescriptor::ReceiverRegister()); 3827 PopOperand(StoreDescriptor::ReceiverRegister());
3840 EmitLoadStoreICSlot(expr->CountSlot()); 3828 EmitLoadStoreICSlot(expr->CountSlot());
3841 CallStoreIC(); 3829 CallStoreIC();
3842 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3830 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3843 if (expr->is_postfix()) { 3831 if (expr->is_postfix()) {
3844 if (!context()->IsEffect()) { 3832 if (!context()->IsEffect()) {
3845 context()->PlugTOS(); 3833 context()->PlugTOS();
3846 } 3834 }
3847 } else { 3835 } else {
3848 context()->Plug(v0); 3836 context()->Plug(v0);
3849 } 3837 }
(...skipping 16 matching lines...) Expand all
3866 if (!context()->IsEffect()) { 3854 if (!context()->IsEffect()) {
3867 context()->PlugTOS(); 3855 context()->PlugTOS();
3868 } 3856 }
3869 } else { 3857 } else {
3870 context()->Plug(v0); 3858 context()->Plug(v0);
3871 } 3859 }
3872 break; 3860 break;
3873 } 3861 }
3874 case KEYED_PROPERTY: { 3862 case KEYED_PROPERTY: {
3875 __ mov(StoreDescriptor::ValueRegister(), result_register()); 3863 __ mov(StoreDescriptor::ValueRegister(), result_register());
3876 __ Pop(StoreDescriptor::ReceiverRegister(), 3864 PopOperands(StoreDescriptor::ReceiverRegister(),
3877 StoreDescriptor::NameRegister()); 3865 StoreDescriptor::NameRegister());
3878 Handle<Code> ic = 3866 Handle<Code> ic =
3879 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3867 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3880 EmitLoadStoreICSlot(expr->CountSlot()); 3868 EmitLoadStoreICSlot(expr->CountSlot());
3881 CallIC(ic); 3869 CallIC(ic);
3882 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3870 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3883 if (expr->is_postfix()) { 3871 if (expr->is_postfix()) {
3884 if (!context()->IsEffect()) { 3872 if (!context()->IsEffect()) {
3885 context()->PlugTOS(); 3873 context()->PlugTOS();
3886 } 3874 }
3887 } else { 3875 } else {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3989 Label* if_false = NULL; 3977 Label* if_false = NULL;
3990 Label* fall_through = NULL; 3978 Label* fall_through = NULL;
3991 context()->PrepareTest(&materialize_true, &materialize_false, 3979 context()->PrepareTest(&materialize_true, &materialize_false,
3992 &if_true, &if_false, &fall_through); 3980 &if_true, &if_false, &fall_through);
3993 3981
3994 Token::Value op = expr->op(); 3982 Token::Value op = expr->op();
3995 VisitForStackValue(expr->left()); 3983 VisitForStackValue(expr->left());
3996 switch (op) { 3984 switch (op) {
3997 case Token::IN: 3985 case Token::IN:
3998 VisitForStackValue(expr->right()); 3986 VisitForStackValue(expr->right());
3999 __ CallRuntime(Runtime::kHasProperty); 3987 CallRuntimeWithOperands(Runtime::kHasProperty);
4000 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3988 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4001 __ LoadRoot(t0, Heap::kTrueValueRootIndex); 3989 __ LoadRoot(t0, Heap::kTrueValueRootIndex);
4002 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); 3990 Split(eq, v0, Operand(t0), if_true, if_false, fall_through);
4003 break; 3991 break;
4004 3992
4005 case Token::INSTANCEOF: { 3993 case Token::INSTANCEOF: {
4006 VisitForAccumulatorValue(expr->right()); 3994 VisitForAccumulatorValue(expr->right());
4007 __ mov(a0, result_register()); 3995 __ mov(a0, result_register());
4008 __ pop(a1); 3996 PopOperand(a1);
4009 InstanceOfStub stub(isolate()); 3997 InstanceOfStub stub(isolate());
4010 __ CallStub(&stub); 3998 __ CallStub(&stub);
4011 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3999 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4012 __ LoadRoot(at, Heap::kTrueValueRootIndex); 4000 __ LoadRoot(at, Heap::kTrueValueRootIndex);
4013 Split(eq, v0, Operand(at), if_true, if_false, fall_through); 4001 Split(eq, v0, Operand(at), if_true, if_false, fall_through);
4014 break; 4002 break;
4015 } 4003 }
4016 4004
4017 default: { 4005 default: {
4018 VisitForAccumulatorValue(expr->right()); 4006 VisitForAccumulatorValue(expr->right());
4019 Condition cc = CompareIC::ComputeCondition(op); 4007 Condition cc = CompareIC::ComputeCondition(op);
4020 __ mov(a0, result_register()); 4008 __ mov(a0, result_register());
4021 __ pop(a1); 4009 PopOperand(a1);
4022 4010
4023 bool inline_smi_code = ShouldInlineSmiCase(op); 4011 bool inline_smi_code = ShouldInlineSmiCase(op);
4024 JumpPatchSite patch_site(masm_); 4012 JumpPatchSite patch_site(masm_);
4025 if (inline_smi_code) { 4013 if (inline_smi_code) {
4026 Label slow_case; 4014 Label slow_case;
4027 __ Or(a2, a0, Operand(a1)); 4015 __ Or(a2, a0, Operand(a1));
4028 patch_site.EmitJumpIfNotSmi(a2, &slow_case); 4016 patch_site.EmitJumpIfNotSmi(a2, &slow_case);
4029 Split(cc, a1, Operand(a0), if_true, if_false, NULL); 4017 Split(cc, a1, Operand(a0), if_true, if_false, NULL);
4030 __ bind(&slow_case); 4018 __ bind(&slow_case);
4031 } 4019 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
4110 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, at); 4098 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, at);
4111 } else if (closure_scope->is_eval_scope()) { 4099 } else if (closure_scope->is_eval_scope()) {
4112 // Contexts created by a call to eval have the same closure as the 4100 // Contexts created by a call to eval have the same closure as the
4113 // context calling eval, not the anonymous closure containing the eval 4101 // context calling eval, not the anonymous closure containing the eval
4114 // code. Fetch it from the context. 4102 // code. Fetch it from the context.
4115 __ lw(at, ContextMemOperand(cp, Context::CLOSURE_INDEX)); 4103 __ lw(at, ContextMemOperand(cp, Context::CLOSURE_INDEX));
4116 } else { 4104 } else {
4117 DCHECK(closure_scope->is_function_scope()); 4105 DCHECK(closure_scope->is_function_scope());
4118 __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4106 __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4119 } 4107 }
4120 __ push(at); 4108 PushOperand(at);
4121 } 4109 }
4122 4110
4123 4111
4124 // ---------------------------------------------------------------------------- 4112 // ----------------------------------------------------------------------------
4125 // Non-local control flow support. 4113 // Non-local control flow support.
4126 4114
4127 void FullCodeGenerator::EnterFinallyBlock() { 4115 void FullCodeGenerator::EnterFinallyBlock() {
4128 DCHECK(!result_register().is(a1)); 4116 DCHECK(!result_register().is(a1));
4129 // Store pending message while executing finally block. 4117 // Store pending message while executing finally block.
4130 ExternalReference pending_message_obj = 4118 ExternalReference pending_message_obj =
4131 ExternalReference::address_of_pending_message_obj(isolate()); 4119 ExternalReference::address_of_pending_message_obj(isolate());
4132 __ li(at, Operand(pending_message_obj)); 4120 __ li(at, Operand(pending_message_obj));
4133 __ lw(a1, MemOperand(at)); 4121 __ lw(a1, MemOperand(at));
4134 __ push(a1); 4122 PushOperand(a1);
4135 4123
4136 ClearPendingMessage(); 4124 ClearPendingMessage();
4137 } 4125 }
4138 4126
4139 4127
4140 void FullCodeGenerator::ExitFinallyBlock() { 4128 void FullCodeGenerator::ExitFinallyBlock() {
4141 DCHECK(!result_register().is(a1)); 4129 DCHECK(!result_register().is(a1));
4142 // Restore pending message from stack. 4130 // Restore pending message from stack.
4143 __ pop(a1); 4131 PopOperand(a1);
4144 ExternalReference pending_message_obj = 4132 ExternalReference pending_message_obj =
4145 ExternalReference::address_of_pending_message_obj(isolate()); 4133 ExternalReference::address_of_pending_message_obj(isolate());
4146 __ li(at, Operand(pending_message_obj)); 4134 __ li(at, Operand(pending_message_obj));
4147 __ sw(a1, MemOperand(at)); 4135 __ sw(a1, MemOperand(at));
4148 } 4136 }
4149 4137
4150 4138
4151 void FullCodeGenerator::ClearPendingMessage() { 4139 void FullCodeGenerator::ClearPendingMessage() {
4152 DCHECK(!result_register().is(a1)); 4140 DCHECK(!result_register().is(a1));
4153 ExternalReference pending_message_obj = 4141 ExternalReference pending_message_obj =
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
4268 reinterpret_cast<uint32_t>( 4256 reinterpret_cast<uint32_t>(
4269 isolate->builtins()->OsrAfterStackCheck()->entry())); 4257 isolate->builtins()->OsrAfterStackCheck()->entry()));
4270 return OSR_AFTER_STACK_CHECK; 4258 return OSR_AFTER_STACK_CHECK;
4271 } 4259 }
4272 4260
4273 4261
4274 } // namespace internal 4262 } // namespace internal
4275 } // namespace v8 4263 } // namespace v8
4276 4264
4277 #endif // V8_TARGET_ARCH_MIPS 4265 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/full-codegen/ia32/full-codegen-ia32.cc ('k') | src/full-codegen/mips64/full-codegen-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698