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

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

Issue 1719003005: MIPS64: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 // Note on Mips implementation: 7 // Note on Mips implementation:
8 // 8 //
9 // The result_register() for mips is the 'v0' register, which is defined 9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first 10 // by the ABI to contain function return values. However, the first
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 // MANUAL indicates that the scope shouldn't actually generate code to set up 131 // MANUAL indicates that the scope shouldn't actually generate code to set up
132 // the frame (that is done below). 132 // the frame (that is done below).
133 FrameScope frame_scope(masm_, StackFrame::MANUAL); 133 FrameScope frame_scope(masm_, StackFrame::MANUAL);
134 info->set_prologue_offset(masm_->pc_offset()); 134 info->set_prologue_offset(masm_->pc_offset());
135 __ Prologue(info->GeneratePreagedPrologue()); 135 __ Prologue(info->GeneratePreagedPrologue());
136 136
137 { Comment cmnt(masm_, "[ Allocate locals"); 137 { Comment cmnt(masm_, "[ Allocate locals");
138 int locals_count = info->scope()->num_stack_slots(); 138 int locals_count = info->scope()->num_stack_slots();
139 // Generators allocate locals, if any, in context slots. 139 // Generators allocate locals, if any, in context slots.
140 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 140 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
141 OperandStackDepthIncrement(locals_count);
141 if (locals_count > 0) { 142 if (locals_count > 0) {
142 if (locals_count >= 128) { 143 if (locals_count >= 128) {
143 Label ok; 144 Label ok;
144 __ Dsubu(t1, sp, Operand(locals_count * kPointerSize)); 145 __ Dsubu(t1, sp, Operand(locals_count * kPointerSize));
145 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); 146 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
146 __ Branch(&ok, hs, t1, Operand(a2)); 147 __ Branch(&ok, hs, t1, Operand(a2));
147 __ CallRuntime(Runtime::kThrowStackOverflow); 148 __ CallRuntime(Runtime::kThrowStackOverflow);
148 __ bind(&ok); 149 __ bind(&ok);
149 } 150 }
150 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex); 151 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 masm_->Daddu(sp, sp, Operand(sp_delta)); 459 masm_->Daddu(sp, sp, Operand(sp_delta));
459 masm_->Jump(ra); 460 masm_->Jump(ra);
460 } 461 }
461 } 462 }
462 } 463 }
463 464
464 465
465 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 466 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
466 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 467 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
467 codegen()->GetVar(result_register(), var); 468 codegen()->GetVar(result_register(), var);
468 __ push(result_register()); 469 codegen()->PushOperand(result_register());
469 } 470 }
470 471
471 472
472 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 473 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
473 } 474 }
474 475
475 476
476 void FullCodeGenerator::AccumulatorValueContext::Plug( 477 void FullCodeGenerator::AccumulatorValueContext::Plug(
477 Heap::RootListIndex index) const { 478 Heap::RootListIndex index) const {
478 __ LoadRoot(result_register(), index); 479 __ LoadRoot(result_register(), index);
479 } 480 }
480 481
481 482
482 void FullCodeGenerator::StackValueContext::Plug( 483 void FullCodeGenerator::StackValueContext::Plug(
483 Heap::RootListIndex index) const { 484 Heap::RootListIndex index) const {
484 __ LoadRoot(result_register(), index); 485 __ LoadRoot(result_register(), index);
485 __ push(result_register()); 486 codegen()->PushOperand(result_register());
486 } 487 }
487 488
488 489
489 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 490 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
490 codegen()->PrepareForBailoutBeforeSplit(condition(), 491 codegen()->PrepareForBailoutBeforeSplit(condition(),
491 true, 492 true,
492 true_label_, 493 true_label_,
493 false_label_); 494 false_label_);
494 if (index == Heap::kUndefinedValueRootIndex || 495 if (index == Heap::kUndefinedValueRootIndex ||
495 index == Heap::kNullValueRootIndex || 496 index == Heap::kNullValueRootIndex ||
(...skipping 14 matching lines...) Expand all
510 511
511 void FullCodeGenerator::AccumulatorValueContext::Plug( 512 void FullCodeGenerator::AccumulatorValueContext::Plug(
512 Handle<Object> lit) const { 513 Handle<Object> lit) const {
513 __ li(result_register(), Operand(lit)); 514 __ li(result_register(), Operand(lit));
514 } 515 }
515 516
516 517
517 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 518 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
518 // Immediates cannot be pushed directly. 519 // Immediates cannot be pushed directly.
519 __ li(result_register(), Operand(lit)); 520 __ li(result_register(), Operand(lit));
520 __ push(result_register()); 521 codegen()->PushOperand(result_register());
521 } 522 }
522 523
523 524
524 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 525 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
525 codegen()->PrepareForBailoutBeforeSplit(condition(), 526 codegen()->PrepareForBailoutBeforeSplit(condition(),
526 true, 527 true,
527 true_label_, 528 true_label_,
528 false_label_); 529 false_label_);
529 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); 530 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject());
530 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 531 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 Register reg) const { 564 Register reg) const {
564 DCHECK(count > 0); 565 DCHECK(count > 0);
565 __ Drop(count); 566 __ Drop(count);
566 __ Move(result_register(), reg); 567 __ Move(result_register(), reg);
567 } 568 }
568 569
569 570
570 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 571 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
571 Register reg) const { 572 Register reg) const {
572 DCHECK(count > 0); 573 DCHECK(count > 0);
573 if (count > 1) __ Drop(count - 1); 574 if (count > 1) codegen()->DropOperands(count - 1);
574 __ sd(reg, MemOperand(sp, 0)); 575 __ sd(reg, MemOperand(sp, 0));
575 } 576 }
576 577
577 578
578 void FullCodeGenerator::TestContext::DropAndPlug(int count, 579 void FullCodeGenerator::TestContext::DropAndPlug(int count,
579 Register reg) const { 580 Register reg) const {
580 DCHECK(count > 0); 581 DCHECK(count > 0);
581 // For simplicity we always test the accumulator register. 582 // For simplicity we always test the accumulator register.
582 __ Drop(count); 583 __ Drop(count);
583 __ Move(result_register(), reg); 584 __ Move(result_register(), reg);
(...skipping 18 matching lines...) Expand all
602 __ Branch(&done); 603 __ Branch(&done);
603 __ bind(materialize_false); 604 __ bind(materialize_false);
604 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); 605 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
605 __ bind(&done); 606 __ bind(&done);
606 } 607 }
607 608
608 609
609 void FullCodeGenerator::StackValueContext::Plug( 610 void FullCodeGenerator::StackValueContext::Plug(
610 Label* materialize_true, 611 Label* materialize_true,
611 Label* materialize_false) const { 612 Label* materialize_false) const {
613 codegen()->OperandStackDepthIncrement(1);
612 Label done; 614 Label done;
613 __ bind(materialize_true); 615 __ bind(materialize_true);
614 __ LoadRoot(at, Heap::kTrueValueRootIndex); 616 __ LoadRoot(at, Heap::kTrueValueRootIndex);
615 // Push the value as the following branch can clobber at in long branch mode. 617 // Push the value as the following branch can clobber at in long branch mode.
616 __ push(at); 618 __ push(at);
617 __ Branch(&done); 619 __ Branch(&done);
618 __ bind(materialize_false); 620 __ bind(materialize_false);
619 __ LoadRoot(at, Heap::kFalseValueRootIndex); 621 __ LoadRoot(at, Heap::kFalseValueRootIndex);
620 __ push(at); 622 __ push(at);
621 __ bind(&done); 623 __ bind(&done);
(...skipping 11 matching lines...) Expand all
633 Heap::RootListIndex value_root_index = 635 Heap::RootListIndex value_root_index =
634 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 636 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
635 __ LoadRoot(result_register(), value_root_index); 637 __ LoadRoot(result_register(), value_root_index);
636 } 638 }
637 639
638 640
639 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 641 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
640 Heap::RootListIndex value_root_index = 642 Heap::RootListIndex value_root_index =
641 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 643 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
642 __ LoadRoot(at, value_root_index); 644 __ LoadRoot(at, value_root_index);
643 __ push(at); 645 codegen()->PushOperand(at);
644 } 646 }
645 647
646 648
647 void FullCodeGenerator::TestContext::Plug(bool flag) const { 649 void FullCodeGenerator::TestContext::Plug(bool flag) const {
648 codegen()->PrepareForBailoutBeforeSplit(condition(), 650 codegen()->PrepareForBailoutBeforeSplit(condition(),
649 true, 651 true,
650 true_label_, 652 true_label_,
651 false_label_); 653 false_label_);
652 if (flag) { 654 if (flag) {
653 if (true_label_ != fall_through_) __ Branch(true_label_); 655 if (true_label_ != fall_through_) __ Branch(true_label_);
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 kDontSaveFPRegs, 882 kDontSaveFPRegs,
881 EMIT_REMEMBERED_SET, 883 EMIT_REMEMBERED_SET,
882 OMIT_SMI_CHECK); 884 OMIT_SMI_CHECK);
883 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 885 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
884 break; 886 break;
885 } 887 }
886 888
887 case VariableLocation::LOOKUP: { 889 case VariableLocation::LOOKUP: {
888 Comment cmnt(masm_, "[ FunctionDeclaration"); 890 Comment cmnt(masm_, "[ FunctionDeclaration");
889 __ li(a2, Operand(variable->name())); 891 __ li(a2, Operand(variable->name()));
890 __ Push(a2); 892 PushOperand(a2);
891 // Push initial value for function declaration. 893 // Push initial value for function declaration.
892 VisitForStackValue(declaration->fun()); 894 VisitForStackValue(declaration->fun());
893 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 895 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
894 __ CallRuntime(Runtime::kDeclareLookupSlot); 896 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
895 break; 897 break;
896 } 898 }
897 } 899 }
898 } 900 }
899 901
900 902
901 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 903 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
902 // Call the runtime to declare the globals. 904 // Call the runtime to declare the globals.
903 __ li(a1, Operand(pairs)); 905 __ li(a1, Operand(pairs));
904 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 906 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 __ bind(&skip); 983 __ bind(&skip);
982 984
983 __ Branch(&next_test, ne, v0, Operand(zero_reg)); 985 __ Branch(&next_test, ne, v0, Operand(zero_reg));
984 __ Drop(1); // Switch value is no longer needed. 986 __ Drop(1); // Switch value is no longer needed.
985 __ Branch(clause->body_target()); 987 __ Branch(clause->body_target());
986 } 988 }
987 989
988 // Discard the test value and jump to the default if present, otherwise to 990 // Discard the test value and jump to the default if present, otherwise to
989 // the end of the statement. 991 // the end of the statement.
990 __ bind(&next_test); 992 __ bind(&next_test);
991 __ Drop(1); // Switch value is no longer needed. 993 DropOperands(1); // Switch value is no longer needed.
992 if (default_clause == NULL) { 994 if (default_clause == NULL) {
993 __ Branch(nested_statement.break_label()); 995 __ Branch(nested_statement.break_label());
994 } else { 996 } else {
995 __ Branch(default_clause->body_target()); 997 __ Branch(default_clause->body_target());
996 } 998 }
997 999
998 // Compile all the case bodies. 1000 // Compile all the case bodies.
999 for (int i = 0; i < clauses->length(); i++) { 1001 for (int i = 0; i < clauses->length(); i++) {
1000 Comment cmnt(masm_, "[ Case body"); 1002 Comment cmnt(masm_, "[ Case body");
1001 CaseClause* clause = clauses->at(i); 1003 CaseClause* clause = clauses->at(i);
(...skipping 15 matching lines...) Expand all
1017 1019
1018 Label loop, exit; 1020 Label loop, exit;
1019 ForIn loop_statement(this, stmt); 1021 ForIn loop_statement(this, stmt);
1020 increment_loop_depth(); 1022 increment_loop_depth();
1021 1023
1022 // Get the object to enumerate over. If the object is null or undefined, skip 1024 // Get the object to enumerate over. If the object is null or undefined, skip
1023 // over the loop. See ECMA-262 version 5, section 12.6.4. 1025 // over the loop. See ECMA-262 version 5, section 12.6.4.
1024 SetExpressionAsStatementPosition(stmt->enumerable()); 1026 SetExpressionAsStatementPosition(stmt->enumerable());
1025 VisitForAccumulatorValue(stmt->enumerable()); 1027 VisitForAccumulatorValue(stmt->enumerable());
1026 __ mov(a0, result_register()); 1028 __ mov(a0, result_register());
1029 OperandStackDepthIncrement(ForIn::kElementCount);
1027 1030
1028 // If the object is null or undefined, skip over the loop, otherwise convert 1031 // If the object is null or undefined, skip over the loop, otherwise convert
1029 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 1032 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
1030 Label convert, done_convert; 1033 Label convert, done_convert;
1031 __ JumpIfSmi(a0, &convert); 1034 __ JumpIfSmi(a0, &convert);
1032 __ GetObjectType(a0, a1, a1); 1035 __ GetObjectType(a0, a1, a1);
1033 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, 1036 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1,
1034 Operand(FIRST_JS_RECEIVER_TYPE)); 1037 Operand(FIRST_JS_RECEIVER_TYPE));
1035 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. 1038 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot.
1036 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); 1039 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at));
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 __ bind(loop_statement.continue_label()); 1180 __ bind(loop_statement.continue_label());
1178 __ pop(a0); 1181 __ pop(a0);
1179 __ Daddu(a0, a0, Operand(Smi::FromInt(1))); 1182 __ Daddu(a0, a0, Operand(Smi::FromInt(1)));
1180 __ push(a0); 1183 __ push(a0);
1181 1184
1182 EmitBackEdgeBookkeeping(stmt, &loop); 1185 EmitBackEdgeBookkeeping(stmt, &loop);
1183 __ Branch(&loop); 1186 __ Branch(&loop);
1184 1187
1185 // Remove the pointers stored on the stack. 1188 // Remove the pointers stored on the stack.
1186 __ bind(loop_statement.break_label()); 1189 __ bind(loop_statement.break_label());
1187 __ Drop(5); 1190 DropOperands(5);
1188 1191
1189 // Exit and decrement the loop depth. 1192 // Exit and decrement the loop depth.
1190 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1193 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1191 __ bind(&exit); 1194 __ bind(&exit);
1192 decrement_loop_depth(); 1195 decrement_loop_depth();
1193 } 1196 }
1194 1197
1195 1198
1196 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1199 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1197 bool pretenure) { 1200 bool pretenure) {
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 FastCloneRegExpStub stub(isolate()); 1456 FastCloneRegExpStub stub(isolate());
1454 __ CallStub(&stub); 1457 __ CallStub(&stub);
1455 context()->Plug(v0); 1458 context()->Plug(v0);
1456 } 1459 }
1457 1460
1458 1461
1459 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1462 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1460 Expression* expression = (property == NULL) ? NULL : property->value(); 1463 Expression* expression = (property == NULL) ? NULL : property->value();
1461 if (expression == NULL) { 1464 if (expression == NULL) {
1462 __ LoadRoot(a1, Heap::kNullValueRootIndex); 1465 __ LoadRoot(a1, Heap::kNullValueRootIndex);
1463 __ push(a1); 1466 PushOperand(a1);
1464 } else { 1467 } else {
1465 VisitForStackValue(expression); 1468 VisitForStackValue(expression);
1466 if (NeedsHomeObject(expression)) { 1469 if (NeedsHomeObject(expression)) {
1467 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1470 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1468 property->kind() == ObjectLiteral::Property::SETTER); 1471 property->kind() == ObjectLiteral::Property::SETTER);
1469 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1472 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1470 EmitSetHomeObject(expression, offset, property->GetSlot()); 1473 EmitSetHomeObject(expression, offset, property->GetSlot());
1471 } 1474 }
1472 } 1475 }
1473 } 1476 }
(...skipping 23 matching lines...) Expand all
1497 AccessorTable accessor_table(zone()); 1500 AccessorTable accessor_table(zone());
1498 int property_index = 0; 1501 int property_index = 0;
1499 for (; property_index < expr->properties()->length(); property_index++) { 1502 for (; property_index < expr->properties()->length(); property_index++) {
1500 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1503 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1501 if (property->is_computed_name()) break; 1504 if (property->is_computed_name()) break;
1502 if (property->IsCompileTimeValue()) continue; 1505 if (property->IsCompileTimeValue()) continue;
1503 1506
1504 Literal* key = property->key()->AsLiteral(); 1507 Literal* key = property->key()->AsLiteral();
1505 Expression* value = property->value(); 1508 Expression* value = property->value();
1506 if (!result_saved) { 1509 if (!result_saved) {
1507 __ push(v0); // Save result on stack. 1510 PushOperand(v0); // Save result on stack.
1508 result_saved = true; 1511 result_saved = true;
1509 } 1512 }
1510 switch (property->kind()) { 1513 switch (property->kind()) {
1511 case ObjectLiteral::Property::CONSTANT: 1514 case ObjectLiteral::Property::CONSTANT:
1512 UNREACHABLE(); 1515 UNREACHABLE();
1513 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1516 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1514 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1517 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1515 // Fall through. 1518 // Fall through.
1516 case ObjectLiteral::Property::COMPUTED: 1519 case ObjectLiteral::Property::COMPUTED:
1517 // It is safe to use [[Put]] here because the boilerplate already 1520 // It is safe to use [[Put]] here because the boilerplate already
(...skipping 12 matching lines...) Expand all
1530 if (NeedsHomeObject(value)) { 1533 if (NeedsHomeObject(value)) {
1531 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1534 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1532 } 1535 }
1533 } else { 1536 } else {
1534 VisitForEffect(value); 1537 VisitForEffect(value);
1535 } 1538 }
1536 break; 1539 break;
1537 } 1540 }
1538 // Duplicate receiver on stack. 1541 // Duplicate receiver on stack.
1539 __ ld(a0, MemOperand(sp)); 1542 __ ld(a0, MemOperand(sp));
1540 __ push(a0); 1543 PushOperand(a0);
1541 VisitForStackValue(key); 1544 VisitForStackValue(key);
1542 VisitForStackValue(value); 1545 VisitForStackValue(value);
1543 if (property->emit_store()) { 1546 if (property->emit_store()) {
1544 if (NeedsHomeObject(value)) { 1547 if (NeedsHomeObject(value)) {
1545 EmitSetHomeObject(value, 2, property->GetSlot()); 1548 EmitSetHomeObject(value, 2, property->GetSlot());
1546 } 1549 }
1547 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. 1550 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes.
1548 __ push(a0); 1551 PushOperand(a0);
1549 __ CallRuntime(Runtime::kSetProperty); 1552 CallRuntimeWithOperands(Runtime::kSetProperty);
1550 } else { 1553 } else {
1551 __ Drop(3); 1554 DropOperands(3);
1552 } 1555 }
1553 break; 1556 break;
1554 case ObjectLiteral::Property::PROTOTYPE: 1557 case ObjectLiteral::Property::PROTOTYPE:
1555 // Duplicate receiver on stack. 1558 // Duplicate receiver on stack.
1556 __ ld(a0, MemOperand(sp)); 1559 __ ld(a0, MemOperand(sp));
1557 __ push(a0); 1560 PushOperand(a0);
1558 VisitForStackValue(value); 1561 VisitForStackValue(value);
1559 DCHECK(property->emit_store()); 1562 DCHECK(property->emit_store());
1560 __ CallRuntime(Runtime::kInternalSetPrototype); 1563 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1561 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1564 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1562 NO_REGISTERS); 1565 NO_REGISTERS);
1563 break; 1566 break;
1564 case ObjectLiteral::Property::GETTER: 1567 case ObjectLiteral::Property::GETTER:
1565 if (property->emit_store()) { 1568 if (property->emit_store()) {
1566 accessor_table.lookup(key)->second->getter = property; 1569 accessor_table.lookup(key)->second->getter = property;
1567 } 1570 }
1568 break; 1571 break;
1569 case ObjectLiteral::Property::SETTER: 1572 case ObjectLiteral::Property::SETTER:
1570 if (property->emit_store()) { 1573 if (property->emit_store()) {
1571 accessor_table.lookup(key)->second->setter = property; 1574 accessor_table.lookup(key)->second->setter = property;
1572 } 1575 }
1573 break; 1576 break;
1574 } 1577 }
1575 } 1578 }
1576 1579
1577 // Emit code to define accessors, using only a single call to the runtime for 1580 // Emit code to define accessors, using only a single call to the runtime for
1578 // each pair of corresponding getters and setters. 1581 // each pair of corresponding getters and setters.
1579 for (AccessorTable::Iterator it = accessor_table.begin(); 1582 for (AccessorTable::Iterator it = accessor_table.begin();
1580 it != accessor_table.end(); 1583 it != accessor_table.end();
1581 ++it) { 1584 ++it) {
1582 __ ld(a0, MemOperand(sp)); // Duplicate receiver. 1585 __ ld(a0, MemOperand(sp)); // Duplicate receiver.
1583 __ push(a0); 1586 PushOperand(a0);
1584 VisitForStackValue(it->first); 1587 VisitForStackValue(it->first);
1585 EmitAccessor(it->second->getter); 1588 EmitAccessor(it->second->getter);
1586 EmitAccessor(it->second->setter); 1589 EmitAccessor(it->second->setter);
1587 __ li(a0, Operand(Smi::FromInt(NONE))); 1590 __ li(a0, Operand(Smi::FromInt(NONE)));
1588 __ push(a0); 1591 PushOperand(a0);
1589 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1592 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1590 } 1593 }
1591 1594
1592 // Object literals have two parts. The "static" part on the left contains no 1595 // Object literals have two parts. The "static" part on the left contains no
1593 // computed property names, and so we can compute its map ahead of time; see 1596 // computed property names, and so we can compute its map ahead of time; see
1594 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1597 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1595 // starts with the first computed property name, and continues with all 1598 // starts with the first computed property name, and continues with all
1596 // properties to its right. All the code from above initializes the static 1599 // properties to its right. All the code from above initializes the static
1597 // component of the object literal, and arranges for the map of the result to 1600 // component of the object literal, and arranges for the map of the result to
1598 // reflect the static order in which the keys appear. For the dynamic 1601 // reflect the static order in which the keys appear. For the dynamic
1599 // properties, we compile them into a series of "SetOwnProperty" runtime 1602 // properties, we compile them into a series of "SetOwnProperty" runtime
1600 // calls. This will preserve insertion order. 1603 // calls. This will preserve insertion order.
1601 for (; property_index < expr->properties()->length(); property_index++) { 1604 for (; property_index < expr->properties()->length(); property_index++) {
1602 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1605 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1603 1606
1604 Expression* value = property->value(); 1607 Expression* value = property->value();
1605 if (!result_saved) { 1608 if (!result_saved) {
1606 __ push(v0); // Save result on the stack 1609 PushOperand(v0); // Save result on the stack
1607 result_saved = true; 1610 result_saved = true;
1608 } 1611 }
1609 1612
1610 __ ld(a0, MemOperand(sp)); // Duplicate receiver. 1613 __ ld(a0, MemOperand(sp)); // Duplicate receiver.
1611 __ push(a0); 1614 PushOperand(a0);
1612 1615
1613 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1616 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1614 DCHECK(!property->is_computed_name()); 1617 DCHECK(!property->is_computed_name());
1615 VisitForStackValue(value); 1618 VisitForStackValue(value);
1616 DCHECK(property->emit_store()); 1619 DCHECK(property->emit_store());
1617 __ CallRuntime(Runtime::kInternalSetPrototype); 1620 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1618 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1621 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1619 NO_REGISTERS); 1622 NO_REGISTERS);
1620 } else { 1623 } else {
1621 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1624 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1622 VisitForStackValue(value); 1625 VisitForStackValue(value);
1623 if (NeedsHomeObject(value)) { 1626 if (NeedsHomeObject(value)) {
1624 EmitSetHomeObject(value, 2, property->GetSlot()); 1627 EmitSetHomeObject(value, 2, property->GetSlot());
1625 } 1628 }
1626 1629
1627 switch (property->kind()) { 1630 switch (property->kind()) {
1628 case ObjectLiteral::Property::CONSTANT: 1631 case ObjectLiteral::Property::CONSTANT:
1629 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1632 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1630 case ObjectLiteral::Property::COMPUTED: 1633 case ObjectLiteral::Property::COMPUTED:
1631 if (property->emit_store()) { 1634 if (property->emit_store()) {
1632 __ Push(Smi::FromInt(NONE)); 1635 PushOperand(Smi::FromInt(NONE));
1633 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1636 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1634 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1637 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1635 } else { 1638 } else {
1636 __ Drop(3); 1639 DropOperands(3);
1637 } 1640 }
1638 break; 1641 break;
1639 1642
1640 case ObjectLiteral::Property::PROTOTYPE: 1643 case ObjectLiteral::Property::PROTOTYPE:
1641 UNREACHABLE(); 1644 UNREACHABLE();
1642 break; 1645 break;
1643 1646
1644 case ObjectLiteral::Property::GETTER: 1647 case ObjectLiteral::Property::GETTER:
1645 __ Push(Smi::FromInt(NONE)); 1648 PushOperand(Smi::FromInt(NONE));
1646 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1649 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1647 break; 1650 break;
1648 1651
1649 case ObjectLiteral::Property::SETTER: 1652 case ObjectLiteral::Property::SETTER:
1650 __ Push(Smi::FromInt(NONE)); 1653 PushOperand(Smi::FromInt(NONE));
1651 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1654 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1652 break; 1655 break;
1653 } 1656 }
1654 } 1657 }
1655 } 1658 }
1656 1659
1657 if (expr->has_function()) { 1660 if (expr->has_function()) {
1658 DCHECK(result_saved); 1661 DCHECK(result_saved);
1659 __ ld(a0, MemOperand(sp)); 1662 __ ld(a0, MemOperand(sp));
1660 __ push(a0); 1663 __ push(a0);
1661 __ CallRuntime(Runtime::kToFastProperties); 1664 __ CallRuntime(Runtime::kToFastProperties);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 int array_index = 0; 1709 int array_index = 0;
1707 for (; array_index < length; array_index++) { 1710 for (; array_index < length; array_index++) {
1708 Expression* subexpr = subexprs->at(array_index); 1711 Expression* subexpr = subexprs->at(array_index);
1709 DCHECK(!subexpr->IsSpread()); 1712 DCHECK(!subexpr->IsSpread());
1710 1713
1711 // If the subexpression is a literal or a simple materialized literal it 1714 // If the subexpression is a literal or a simple materialized literal it
1712 // is already set in the cloned array. 1715 // is already set in the cloned array.
1713 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1716 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1714 1717
1715 if (!result_saved) { 1718 if (!result_saved) {
1716 __ push(v0); // array literal 1719 PushOperand(v0); // array literal
1717 result_saved = true; 1720 result_saved = true;
1718 } 1721 }
1719 1722
1720 VisitForAccumulatorValue(subexpr); 1723 VisitForAccumulatorValue(subexpr);
1721 1724
1722 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); 1725 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index)));
1723 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1726 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1724 __ mov(StoreDescriptor::ValueRegister(), result_register()); 1727 __ mov(StoreDescriptor::ValueRegister(), result_register());
1725 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1728 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1726 Handle<Code> ic = 1729 Handle<Code> ic =
1727 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1730 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1728 CallIC(ic); 1731 CallIC(ic);
1729 1732
1730 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1733 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1731 } 1734 }
1732 1735
1733 // In case the array literal contains spread expressions it has two parts. The 1736 // In case the array literal contains spread expressions it has two parts. The
1734 // first part is the "static" array which has a literal index is handled 1737 // first part is the "static" array which has a literal index is handled
1735 // above. The second part is the part after the first spread expression 1738 // above. The second part is the part after the first spread expression
1736 // (inclusive) and these elements gets appended to the array. Note that the 1739 // (inclusive) and these elements gets appended to the array. Note that the
1737 // number elements an iterable produces is unknown ahead of time. 1740 // number elements an iterable produces is unknown ahead of time.
1738 if (array_index < length && result_saved) { 1741 if (array_index < length && result_saved) {
1739 __ Pop(v0); 1742 PopOperand(v0);
1740 result_saved = false; 1743 result_saved = false;
1741 } 1744 }
1742 for (; array_index < length; array_index++) { 1745 for (; array_index < length; array_index++) {
1743 Expression* subexpr = subexprs->at(array_index); 1746 Expression* subexpr = subexprs->at(array_index);
1744 1747
1745 __ Push(v0); 1748 PushOperand(v0);
1746 DCHECK(!subexpr->IsSpread()); 1749 DCHECK(!subexpr->IsSpread());
1747 VisitForStackValue(subexpr); 1750 VisitForStackValue(subexpr);
1748 __ CallRuntime(Runtime::kAppendElement); 1751 CallRuntimeWithOperands(Runtime::kAppendElement);
1749 1752
1750 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1753 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1751 } 1754 }
1752 1755
1753 if (result_saved) { 1756 if (result_saved) {
1754 context()->PlugTOS(); 1757 context()->PlugTOS();
1755 } else { 1758 } else {
1756 context()->Plug(v0); 1759 context()->Plug(v0);
1757 } 1760 }
1758 } 1761 }
(...skipping 20 matching lines...) Expand all
1779 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1782 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1780 } else { 1783 } else {
1781 VisitForStackValue(property->obj()); 1784 VisitForStackValue(property->obj());
1782 } 1785 }
1783 break; 1786 break;
1784 case NAMED_SUPER_PROPERTY: 1787 case NAMED_SUPER_PROPERTY:
1785 VisitForStackValue( 1788 VisitForStackValue(
1786 property->obj()->AsSuperPropertyReference()->this_var()); 1789 property->obj()->AsSuperPropertyReference()->this_var());
1787 VisitForAccumulatorValue( 1790 VisitForAccumulatorValue(
1788 property->obj()->AsSuperPropertyReference()->home_object()); 1791 property->obj()->AsSuperPropertyReference()->home_object());
1789 __ Push(result_register()); 1792 PushOperand(result_register());
1790 if (expr->is_compound()) { 1793 if (expr->is_compound()) {
1791 const Register scratch = a1; 1794 const Register scratch = a1;
1792 __ ld(scratch, MemOperand(sp, kPointerSize)); 1795 __ ld(scratch, MemOperand(sp, kPointerSize));
1793 __ Push(scratch, result_register()); 1796 PushOperands(scratch, result_register());
1794 } 1797 }
1795 break; 1798 break;
1796 case KEYED_SUPER_PROPERTY: { 1799 case KEYED_SUPER_PROPERTY: {
1797 const Register scratch = a1; 1800 const Register scratch = a1;
1798 VisitForStackValue( 1801 VisitForStackValue(
1799 property->obj()->AsSuperPropertyReference()->this_var()); 1802 property->obj()->AsSuperPropertyReference()->this_var());
1800 VisitForAccumulatorValue( 1803 VisitForAccumulatorValue(
1801 property->obj()->AsSuperPropertyReference()->home_object()); 1804 property->obj()->AsSuperPropertyReference()->home_object());
1802 __ Move(scratch, result_register()); 1805 __ Move(scratch, result_register());
1803 VisitForAccumulatorValue(property->key()); 1806 VisitForAccumulatorValue(property->key());
1804 __ Push(scratch, result_register()); 1807 PushOperands(scratch, result_register());
1805 if (expr->is_compound()) { 1808 if (expr->is_compound()) {
1806 const Register scratch1 = a4; 1809 const Register scratch1 = a4;
1807 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize)); 1810 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize));
1808 __ Push(scratch1, scratch, result_register()); 1811 PushOperands(scratch1, scratch, result_register());
1809 } 1812 }
1810 break; 1813 break;
1811 } 1814 }
1812 case KEYED_PROPERTY: 1815 case KEYED_PROPERTY:
1813 // We need the key and receiver on both the stack and in v0 and a1. 1816 // We need the key and receiver on both the stack and in v0 and a1.
1814 if (expr->is_compound()) { 1817 if (expr->is_compound()) {
1815 VisitForStackValue(property->obj()); 1818 VisitForStackValue(property->obj());
1816 VisitForStackValue(property->key()); 1819 VisitForStackValue(property->key());
1817 __ ld(LoadDescriptor::ReceiverRegister(), 1820 __ ld(LoadDescriptor::ReceiverRegister(),
1818 MemOperand(sp, 1 * kPointerSize)); 1821 MemOperand(sp, 1 * kPointerSize));
(...skipping 27 matching lines...) Expand all
1846 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1849 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1847 break; 1850 break;
1848 case KEYED_PROPERTY: 1851 case KEYED_PROPERTY:
1849 EmitKeyedPropertyLoad(property); 1852 EmitKeyedPropertyLoad(property);
1850 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1853 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1851 break; 1854 break;
1852 } 1855 }
1853 } 1856 }
1854 1857
1855 Token::Value op = expr->binary_op(); 1858 Token::Value op = expr->binary_op();
1856 __ push(v0); // Left operand goes on the stack. 1859 PushOperand(v0); // Left operand goes on the stack.
1857 VisitForAccumulatorValue(expr->value()); 1860 VisitForAccumulatorValue(expr->value());
1858 1861
1859 AccumulatorValueContext context(this); 1862 AccumulatorValueContext context(this);
1860 if (ShouldInlineSmiCase(op)) { 1863 if (ShouldInlineSmiCase(op)) {
1861 EmitInlineSmiBinaryOp(expr->binary_operation(), 1864 EmitInlineSmiBinaryOp(expr->binary_operation(),
1862 op, 1865 op,
1863 expr->target(), 1866 expr->target(),
1864 expr->value()); 1867 expr->value());
1865 } else { 1868 } else {
1866 EmitBinaryOp(expr->binary_operation(), op); 1869 EmitBinaryOp(expr->binary_operation(), op);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 __ sd(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); 1941 __ sd(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
1939 __ mov(a1, cp); 1942 __ mov(a1, cp);
1940 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, 1943 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2,
1941 kRAHasBeenSaved, kDontSaveFPRegs); 1944 kRAHasBeenSaved, kDontSaveFPRegs);
1942 __ Daddu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1945 __ Daddu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1943 __ Branch(&post_runtime, eq, sp, Operand(a1)); 1946 __ Branch(&post_runtime, eq, sp, Operand(a1));
1944 __ push(v0); // generator object 1947 __ push(v0); // generator object
1945 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1948 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1946 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1949 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1947 __ bind(&post_runtime); 1950 __ bind(&post_runtime);
1948 __ pop(result_register()); 1951 PopOperand(result_register());
1949 EmitReturnSequence(); 1952 EmitReturnSequence();
1950 1953
1951 __ bind(&resume); 1954 __ bind(&resume);
1952 context()->Plug(result_register()); 1955 context()->Plug(result_register());
1953 break; 1956 break;
1954 } 1957 }
1955 1958
1956 case Yield::kFinal: { 1959 case Yield::kFinal: {
1957 // Pop value from top-of-stack slot, box result into result register. 1960 // Pop value from top-of-stack slot, box result into result register.
1961 OperandStackDepthDecrement(1);
1958 EmitCreateIteratorResult(true); 1962 EmitCreateIteratorResult(true);
1959 EmitUnwindAndReturn(); 1963 EmitUnwindAndReturn();
1960 break; 1964 break;
1961 } 1965 }
1962 1966
1963 case Yield::kDelegating: 1967 case Yield::kDelegating:
1964 UNREACHABLE(); 1968 UNREACHABLE();
1965 } 1969 }
1966 } 1970 }
1967 1971
1968 1972
1969 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 1973 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1970 Expression *value, 1974 Expression *value,
1971 JSGeneratorObject::ResumeMode resume_mode) { 1975 JSGeneratorObject::ResumeMode resume_mode) {
1972 // The value stays in a0, and is ultimately read by the resumed generator, as 1976 // The value stays in a0, and is ultimately read by the resumed generator, as
1973 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1977 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1974 // is read to throw the value when the resumed generator is already closed. 1978 // is read to throw the value when the resumed generator is already closed.
1975 // a1 will hold the generator object until the activation has been resumed. 1979 // a1 will hold the generator object until the activation has been resumed.
1976 VisitForStackValue(generator); 1980 VisitForStackValue(generator);
1977 VisitForAccumulatorValue(value); 1981 VisitForAccumulatorValue(value);
1978 __ pop(a1); 1982 PopOperand(a1);
1979 1983
1980 // Store input value into generator object. 1984 // Store input value into generator object.
1981 __ sd(result_register(), 1985 __ sd(result_register(),
1982 FieldMemOperand(a1, JSGeneratorObject::kInputOffset)); 1986 FieldMemOperand(a1, JSGeneratorObject::kInputOffset));
1983 __ mov(a2, result_register()); 1987 __ mov(a2, result_register());
1984 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3, 1988 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3,
1985 kRAHasBeenSaved, kDontSaveFPRegs); 1989 kRAHasBeenSaved, kDontSaveFPRegs);
1986 1990
1987 // Load suspended function and context. 1991 // Load suspended function and context.
1988 __ ld(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset)); 1992 __ ld(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2056 __ Push(a1, result_register()); 2060 __ Push(a1, result_register());
2057 __ Push(Smi::FromInt(resume_mode)); 2061 __ Push(Smi::FromInt(resume_mode));
2058 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 2062 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
2059 // Not reached: the runtime call returns elsewhere. 2063 // Not reached: the runtime call returns elsewhere.
2060 __ stop("not-reached"); 2064 __ stop("not-reached");
2061 2065
2062 __ bind(&done); 2066 __ bind(&done);
2063 context()->Plug(result_register()); 2067 context()->Plug(result_register());
2064 } 2068 }
2065 2069
2070 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
2071 OperandStackDepthIncrement(2);
2072 __ Push(reg1, reg2);
2073 }
2074
2075 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
2076 Register reg3) {
2077 OperandStackDepthIncrement(3);
2078 __ Push(reg1, reg2, reg3);
2079 }
2080
2081 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
2082 Register reg3, Register reg4) {
2083 OperandStackDepthIncrement(4);
2084 __ Push(reg1, reg2, reg3, reg4);
2085 }
2086
2087 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) {
2088 OperandStackDepthDecrement(2);
2089 __ Pop(reg1, reg2);
2090 }
2091
2092 void FullCodeGenerator::EmitOperandStackDepthCheck() {
2093 if (generate_debug_code_) {
2094 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
2095 operand_stack_depth_ * kPointerSize;
2096 __ Dsubu(v0, fp, sp);
2097 __ Assert(eq, kUnexpectedStackDepth, v0, Operand(expected_diff));
2098 }
2099 }
2066 2100
2067 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2101 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2068 Label allocate, done_allocate; 2102 Label allocate, done_allocate;
2069 2103
2070 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); 2104 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
2071 __ jmp(&done_allocate); 2105 __ jmp(&done_allocate);
2072 2106
2073 __ bind(&allocate); 2107 __ bind(&allocate);
2074 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2108 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2075 __ CallRuntime(Runtime::kAllocateInNewSpace); 2109 __ CallRuntime(Runtime::kAllocateInNewSpace);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 Expression* left_expr, 2171 Expression* left_expr,
2138 Expression* right_expr) { 2172 Expression* right_expr) {
2139 Label done, smi_case, stub_call; 2173 Label done, smi_case, stub_call;
2140 2174
2141 Register scratch1 = a2; 2175 Register scratch1 = a2;
2142 Register scratch2 = a3; 2176 Register scratch2 = a3;
2143 2177
2144 // Get the arguments. 2178 // Get the arguments.
2145 Register left = a1; 2179 Register left = a1;
2146 Register right = a0; 2180 Register right = a0;
2147 __ pop(left); 2181 PopOperand(left);
2148 __ mov(a0, result_register()); 2182 __ mov(a0, result_register());
2149 2183
2150 // Perform combined smi check on both operands. 2184 // Perform combined smi check on both operands.
2151 __ Or(scratch1, left, Operand(right)); 2185 __ Or(scratch1, left, Operand(right));
2152 STATIC_ASSERT(kSmiTag == 0); 2186 STATIC_ASSERT(kSmiTag == 0);
2153 JumpPatchSite patch_site(masm_); 2187 JumpPatchSite patch_site(masm_);
2154 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2188 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2155 2189
2156 __ bind(&stub_call); 2190 __ bind(&stub_call);
2157 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2191 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2227 for (int i = 0; i < lit->properties()->length(); i++) { 2261 for (int i = 0; i < lit->properties()->length(); i++) {
2228 ObjectLiteral::Property* property = lit->properties()->at(i); 2262 ObjectLiteral::Property* property = lit->properties()->at(i);
2229 Expression* value = property->value(); 2263 Expression* value = property->value();
2230 2264
2231 Register scratch = a1; 2265 Register scratch = a1;
2232 if (property->is_static()) { 2266 if (property->is_static()) {
2233 __ ld(scratch, MemOperand(sp, kPointerSize)); // constructor 2267 __ ld(scratch, MemOperand(sp, kPointerSize)); // constructor
2234 } else { 2268 } else {
2235 __ ld(scratch, MemOperand(sp, 0)); // prototype 2269 __ ld(scratch, MemOperand(sp, 0)); // prototype
2236 } 2270 }
2237 __ push(scratch); 2271 PushOperand(scratch);
2238 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2272 EmitPropertyKey(property, lit->GetIdForProperty(i));
2239 2273
2240 // The static prototype property is read only. We handle the non computed 2274 // The static prototype property is read only. We handle the non computed
2241 // property name case in the parser. Since this is the only case where we 2275 // property name case in the parser. Since this is the only case where we
2242 // need to check for an own read only property we special case this so we do 2276 // need to check for an own read only property we special case this so we do
2243 // not need to do this for every property. 2277 // not need to do this for every property.
2244 if (property->is_static() && property->is_computed_name()) { 2278 if (property->is_static() && property->is_computed_name()) {
2245 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2279 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2246 __ push(v0); 2280 __ push(v0);
2247 } 2281 }
2248 2282
2249 VisitForStackValue(value); 2283 VisitForStackValue(value);
2250 if (NeedsHomeObject(value)) { 2284 if (NeedsHomeObject(value)) {
2251 EmitSetHomeObject(value, 2, property->GetSlot()); 2285 EmitSetHomeObject(value, 2, property->GetSlot());
2252 } 2286 }
2253 2287
2254 switch (property->kind()) { 2288 switch (property->kind()) {
2255 case ObjectLiteral::Property::CONSTANT: 2289 case ObjectLiteral::Property::CONSTANT:
2256 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2290 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2257 case ObjectLiteral::Property::PROTOTYPE: 2291 case ObjectLiteral::Property::PROTOTYPE:
2258 UNREACHABLE(); 2292 UNREACHABLE();
2259 case ObjectLiteral::Property::COMPUTED: 2293 case ObjectLiteral::Property::COMPUTED:
2260 __ Push(Smi::FromInt(DONT_ENUM)); 2294 PushOperand(Smi::FromInt(DONT_ENUM));
2261 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2295 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2262 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2296 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2263 break; 2297 break;
2264 2298
2265 case ObjectLiteral::Property::GETTER: 2299 case ObjectLiteral::Property::GETTER:
2266 __ Push(Smi::FromInt(DONT_ENUM)); 2300 PushOperand(Smi::FromInt(DONT_ENUM));
2267 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2301 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2268 break; 2302 break;
2269 2303
2270 case ObjectLiteral::Property::SETTER: 2304 case ObjectLiteral::Property::SETTER:
2271 __ Push(Smi::FromInt(DONT_ENUM)); 2305 PushOperand(Smi::FromInt(DONT_ENUM));
2272 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2306 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2273 break; 2307 break;
2274 2308
2275 default: 2309 default:
2276 UNREACHABLE(); 2310 UNREACHABLE();
2277 } 2311 }
2278 } 2312 }
2279 } 2313 }
2280 2314
2281 2315
2282 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2316 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2283 __ mov(a0, result_register()); 2317 __ mov(a0, result_register());
2284 __ pop(a1); 2318 PopOperand(a1);
2285 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2319 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2286 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2320 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2287 CallIC(code, expr->BinaryOperationFeedbackId()); 2321 CallIC(code, expr->BinaryOperationFeedbackId());
2288 patch_site.EmitPatchInfo(); 2322 patch_site.EmitPatchInfo();
2289 context()->Plug(v0); 2323 context()->Plug(v0);
2290 } 2324 }
2291 2325
2292 2326
2293 void FullCodeGenerator::EmitAssignment(Expression* expr, 2327 void FullCodeGenerator::EmitAssignment(Expression* expr,
2294 FeedbackVectorSlot slot) { 2328 FeedbackVectorSlot slot) {
2295 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2329 DCHECK(expr->IsValidReferenceExpressionOrThis());
2296 2330
2297 Property* prop = expr->AsProperty(); 2331 Property* prop = expr->AsProperty();
2298 LhsKind assign_type = Property::GetAssignType(prop); 2332 LhsKind assign_type = Property::GetAssignType(prop);
2299 2333
2300 switch (assign_type) { 2334 switch (assign_type) {
2301 case VARIABLE: { 2335 case VARIABLE: {
2302 Variable* var = expr->AsVariableProxy()->var(); 2336 Variable* var = expr->AsVariableProxy()->var();
2303 EffectContext context(this); 2337 EffectContext context(this);
2304 EmitVariableAssignment(var, Token::ASSIGN, slot); 2338 EmitVariableAssignment(var, Token::ASSIGN, slot);
2305 break; 2339 break;
2306 } 2340 }
2307 case NAMED_PROPERTY: { 2341 case NAMED_PROPERTY: {
2308 __ push(result_register()); // Preserve value. 2342 PushOperand(result_register()); // Preserve value.
2309 VisitForAccumulatorValue(prop->obj()); 2343 VisitForAccumulatorValue(prop->obj());
2310 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); 2344 __ mov(StoreDescriptor::ReceiverRegister(), result_register());
2311 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2345 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2312 __ li(StoreDescriptor::NameRegister(), 2346 __ li(StoreDescriptor::NameRegister(),
2313 Operand(prop->key()->AsLiteral()->value())); 2347 Operand(prop->key()->AsLiteral()->value()));
2314 EmitLoadStoreICSlot(slot); 2348 EmitLoadStoreICSlot(slot);
2315 CallStoreIC(); 2349 CallStoreIC();
2316 break; 2350 break;
2317 } 2351 }
2318 case NAMED_SUPER_PROPERTY: { 2352 case NAMED_SUPER_PROPERTY: {
2319 __ Push(v0); 2353 PushOperand(v0);
2320 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2354 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2321 VisitForAccumulatorValue( 2355 VisitForAccumulatorValue(
2322 prop->obj()->AsSuperPropertyReference()->home_object()); 2356 prop->obj()->AsSuperPropertyReference()->home_object());
2323 // stack: value, this; v0: home_object 2357 // stack: value, this; v0: home_object
2324 Register scratch = a2; 2358 Register scratch = a2;
2325 Register scratch2 = a3; 2359 Register scratch2 = a3;
2326 __ mov(scratch, result_register()); // home_object 2360 __ mov(scratch, result_register()); // home_object
2327 __ ld(v0, MemOperand(sp, kPointerSize)); // value 2361 __ ld(v0, MemOperand(sp, kPointerSize)); // value
2328 __ ld(scratch2, MemOperand(sp, 0)); // this 2362 __ ld(scratch2, MemOperand(sp, 0)); // this
2329 __ sd(scratch2, MemOperand(sp, kPointerSize)); // this 2363 __ sd(scratch2, MemOperand(sp, kPointerSize)); // this
2330 __ sd(scratch, MemOperand(sp, 0)); // home_object 2364 __ sd(scratch, MemOperand(sp, 0)); // home_object
2331 // stack: this, home_object; v0: value 2365 // stack: this, home_object; v0: value
2332 EmitNamedSuperPropertyStore(prop); 2366 EmitNamedSuperPropertyStore(prop);
2333 break; 2367 break;
2334 } 2368 }
2335 case KEYED_SUPER_PROPERTY: { 2369 case KEYED_SUPER_PROPERTY: {
2336 __ Push(v0); 2370 PushOperand(v0);
2337 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2371 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2338 VisitForStackValue( 2372 VisitForStackValue(
2339 prop->obj()->AsSuperPropertyReference()->home_object()); 2373 prop->obj()->AsSuperPropertyReference()->home_object());
2340 VisitForAccumulatorValue(prop->key()); 2374 VisitForAccumulatorValue(prop->key());
2341 Register scratch = a2; 2375 Register scratch = a2;
2342 Register scratch2 = a3; 2376 Register scratch2 = a3;
2343 __ ld(scratch2, MemOperand(sp, 2 * kPointerSize)); // value 2377 __ ld(scratch2, MemOperand(sp, 2 * kPointerSize)); // value
2344 // stack: value, this, home_object; v0: key, a3: value 2378 // stack: value, this, home_object; v0: key, a3: value
2345 __ ld(scratch, MemOperand(sp, kPointerSize)); // this 2379 __ ld(scratch, MemOperand(sp, kPointerSize)); // this
2346 __ sd(scratch, MemOperand(sp, 2 * kPointerSize)); 2380 __ sd(scratch, MemOperand(sp, 2 * kPointerSize));
2347 __ ld(scratch, MemOperand(sp, 0)); // home_object 2381 __ ld(scratch, MemOperand(sp, 0)); // home_object
2348 __ sd(scratch, MemOperand(sp, kPointerSize)); 2382 __ sd(scratch, MemOperand(sp, kPointerSize));
2349 __ sd(v0, MemOperand(sp, 0)); 2383 __ sd(v0, MemOperand(sp, 0));
2350 __ Move(v0, scratch2); 2384 __ Move(v0, scratch2);
2351 // stack: this, home_object, key; v0: value. 2385 // stack: this, home_object, key; v0: value.
2352 EmitKeyedSuperPropertyStore(prop); 2386 EmitKeyedSuperPropertyStore(prop);
2353 break; 2387 break;
2354 } 2388 }
2355 case KEYED_PROPERTY: { 2389 case KEYED_PROPERTY: {
2356 __ push(result_register()); // Preserve value. 2390 PushOperand(result_register()); // Preserve value.
2357 VisitForStackValue(prop->obj()); 2391 VisitForStackValue(prop->obj());
2358 VisitForAccumulatorValue(prop->key()); 2392 VisitForAccumulatorValue(prop->key());
2359 __ Move(StoreDescriptor::NameRegister(), result_register()); 2393 __ Move(StoreDescriptor::NameRegister(), result_register());
2360 __ Pop(StoreDescriptor::ValueRegister(), 2394 PopOperands(StoreDescriptor::ValueRegister(),
2361 StoreDescriptor::ReceiverRegister()); 2395 StoreDescriptor::ReceiverRegister());
2362 EmitLoadStoreICSlot(slot); 2396 EmitLoadStoreICSlot(slot);
2363 Handle<Code> ic = 2397 Handle<Code> ic =
2364 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2398 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2365 CallIC(ic); 2399 CallIC(ic);
2366 break; 2400 break;
2367 } 2401 }
2368 } 2402 }
2369 context()->Plug(v0); 2403 context()->Plug(v0);
2370 } 2404 }
2371 2405
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 2524
2491 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2525 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2492 // Assignment to a property, using a named store IC. 2526 // Assignment to a property, using a named store IC.
2493 Property* prop = expr->target()->AsProperty(); 2527 Property* prop = expr->target()->AsProperty();
2494 DCHECK(prop != NULL); 2528 DCHECK(prop != NULL);
2495 DCHECK(prop->key()->IsLiteral()); 2529 DCHECK(prop->key()->IsLiteral());
2496 2530
2497 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2531 __ mov(StoreDescriptor::ValueRegister(), result_register());
2498 __ li(StoreDescriptor::NameRegister(), 2532 __ li(StoreDescriptor::NameRegister(),
2499 Operand(prop->key()->AsLiteral()->value())); 2533 Operand(prop->key()->AsLiteral()->value()));
2500 __ pop(StoreDescriptor::ReceiverRegister()); 2534 PopOperand(StoreDescriptor::ReceiverRegister());
2501 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2535 EmitLoadStoreICSlot(expr->AssignmentSlot());
2502 CallStoreIC(); 2536 CallStoreIC();
2503 2537
2504 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2538 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2505 context()->Plug(v0); 2539 context()->Plug(v0);
2506 } 2540 }
2507 2541
2508 2542
2509 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2543 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2510 // Assignment to named property of super. 2544 // Assignment to named property of super.
2511 // v0 : value 2545 // v0 : value
2512 // stack : receiver ('this'), home_object 2546 // stack : receiver ('this'), home_object
2513 DCHECK(prop != NULL); 2547 DCHECK(prop != NULL);
2514 Literal* key = prop->key()->AsLiteral(); 2548 Literal* key = prop->key()->AsLiteral();
2515 DCHECK(key != NULL); 2549 DCHECK(key != NULL);
2516 2550
2517 __ Push(key->value()); 2551 PushOperand(key->value());
2518 __ Push(v0); 2552 PushOperand(v0);
2519 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2553 CallRuntimeWithOperands(is_strict(language_mode())
2520 : Runtime::kStoreToSuper_Sloppy)); 2554 ? Runtime::kStoreToSuper_Strict
2555 : Runtime::kStoreToSuper_Sloppy);
2521 } 2556 }
2522 2557
2523 2558
2524 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2559 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2525 // Assignment to named property of super. 2560 // Assignment to named property of super.
2526 // v0 : value 2561 // v0 : value
2527 // stack : receiver ('this'), home_object, key 2562 // stack : receiver ('this'), home_object, key
2528 DCHECK(prop != NULL); 2563 DCHECK(prop != NULL);
2529 2564
2530 __ Push(v0); 2565 PushOperand(v0);
2531 __ CallRuntime((is_strict(language_mode()) 2566 CallRuntimeWithOperands(is_strict(language_mode())
2532 ? Runtime::kStoreKeyedToSuper_Strict 2567 ? Runtime::kStoreKeyedToSuper_Strict
2533 : Runtime::kStoreKeyedToSuper_Sloppy)); 2568 : Runtime::kStoreKeyedToSuper_Sloppy);
2534 } 2569 }
2535 2570
2536 2571
2537 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2572 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2538 // Assignment to a property, using a keyed store IC. 2573 // Assignment to a property, using a keyed store IC.
2539 // Call keyed store IC. 2574 // Call keyed store IC.
2540 // The arguments are: 2575 // The arguments are:
2541 // - a0 is the value, 2576 // - a0 is the value,
2542 // - a1 is the key, 2577 // - a1 is the key,
2543 // - a2 is the receiver. 2578 // - a2 is the receiver.
2544 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2579 __ mov(StoreDescriptor::ValueRegister(), result_register());
2545 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2580 PopOperands(StoreDescriptor::ReceiverRegister(),
2581 StoreDescriptor::NameRegister());
2546 DCHECK(StoreDescriptor::ValueRegister().is(a0)); 2582 DCHECK(StoreDescriptor::ValueRegister().is(a0));
2547 2583
2548 Handle<Code> ic = 2584 Handle<Code> ic =
2549 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2585 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2550 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2586 EmitLoadStoreICSlot(expr->AssignmentSlot());
2551 CallIC(ic); 2587 CallIC(ic);
2552 2588
2553 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2589 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2554 context()->Plug(v0); 2590 context()->Plug(v0);
2555 } 2591 }
(...skipping 14 matching lines...) Expand all
2570 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2606 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2571 VisitForStackValue( 2607 VisitForStackValue(
2572 expr->obj()->AsSuperPropertyReference()->home_object()); 2608 expr->obj()->AsSuperPropertyReference()->home_object());
2573 EmitNamedSuperPropertyLoad(expr); 2609 EmitNamedSuperPropertyLoad(expr);
2574 } 2610 }
2575 } else { 2611 } else {
2576 if (!expr->IsSuperAccess()) { 2612 if (!expr->IsSuperAccess()) {
2577 VisitForStackValue(expr->obj()); 2613 VisitForStackValue(expr->obj());
2578 VisitForAccumulatorValue(expr->key()); 2614 VisitForAccumulatorValue(expr->key());
2579 __ Move(LoadDescriptor::NameRegister(), v0); 2615 __ Move(LoadDescriptor::NameRegister(), v0);
2580 __ pop(LoadDescriptor::ReceiverRegister()); 2616 PopOperand(LoadDescriptor::ReceiverRegister());
2581 EmitKeyedPropertyLoad(expr); 2617 EmitKeyedPropertyLoad(expr);
2582 } else { 2618 } else {
2583 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2619 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2584 VisitForStackValue( 2620 VisitForStackValue(
2585 expr->obj()->AsSuperPropertyReference()->home_object()); 2621 expr->obj()->AsSuperPropertyReference()->home_object());
2586 VisitForStackValue(expr->key()); 2622 VisitForStackValue(expr->key());
2587 EmitKeyedSuperPropertyLoad(expr); 2623 EmitKeyedSuperPropertyLoad(expr);
2588 } 2624 }
2589 } 2625 }
2590 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2626 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
(...skipping 15 matching lines...) Expand all
2606 // Get the target function. 2642 // Get the target function.
2607 ConvertReceiverMode convert_mode; 2643 ConvertReceiverMode convert_mode;
2608 if (callee->IsVariableProxy()) { 2644 if (callee->IsVariableProxy()) {
2609 { StackValueContext context(this); 2645 { StackValueContext context(this);
2610 EmitVariableLoad(callee->AsVariableProxy()); 2646 EmitVariableLoad(callee->AsVariableProxy());
2611 PrepareForBailout(callee, NO_REGISTERS); 2647 PrepareForBailout(callee, NO_REGISTERS);
2612 } 2648 }
2613 // Push undefined as receiver. This is patched in the method prologue if it 2649 // Push undefined as receiver. This is patched in the method prologue if it
2614 // is a sloppy mode method. 2650 // is a sloppy mode method.
2615 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 2651 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2616 __ push(at); 2652 PushOperand(at);
2617 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2653 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2618 } else { 2654 } else {
2619 // Load the function from the receiver. 2655 // Load the function from the receiver.
2620 DCHECK(callee->IsProperty()); 2656 DCHECK(callee->IsProperty());
2621 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2657 DCHECK(!callee->AsProperty()->IsSuperAccess());
2622 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2658 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2623 EmitNamedPropertyLoad(callee->AsProperty()); 2659 EmitNamedPropertyLoad(callee->AsProperty());
2624 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2660 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2625 // Push the target function under the receiver. 2661 // Push the target function under the receiver.
2626 __ ld(at, MemOperand(sp, 0)); 2662 __ ld(at, MemOperand(sp, 0));
2627 __ push(at); 2663 PushOperand(at);
2628 __ sd(v0, MemOperand(sp, kPointerSize)); 2664 __ sd(v0, MemOperand(sp, kPointerSize));
2629 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2665 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2630 } 2666 }
2631 2667
2632 EmitCall(expr, convert_mode); 2668 EmitCall(expr, convert_mode);
2633 } 2669 }
2634 2670
2635 2671
2636 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2672 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2637 SetExpressionPosition(expr); 2673 SetExpressionPosition(expr);
2638 Expression* callee = expr->expression(); 2674 Expression* callee = expr->expression();
2639 DCHECK(callee->IsProperty()); 2675 DCHECK(callee->IsProperty());
2640 Property* prop = callee->AsProperty(); 2676 Property* prop = callee->AsProperty();
2641 DCHECK(prop->IsSuperAccess()); 2677 DCHECK(prop->IsSuperAccess());
2642 2678
2643 Literal* key = prop->key()->AsLiteral(); 2679 Literal* key = prop->key()->AsLiteral();
2644 DCHECK(!key->value()->IsSmi()); 2680 DCHECK(!key->value()->IsSmi());
2645 // Load the function from the receiver. 2681 // Load the function from the receiver.
2646 const Register scratch = a1; 2682 const Register scratch = a1;
2647 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2683 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2648 VisitForAccumulatorValue(super_ref->home_object()); 2684 VisitForAccumulatorValue(super_ref->home_object());
2649 __ mov(scratch, v0); 2685 __ mov(scratch, v0);
2650 VisitForAccumulatorValue(super_ref->this_var()); 2686 VisitForAccumulatorValue(super_ref->this_var());
2651 __ Push(scratch, v0, v0, scratch); 2687 PushOperands(scratch, v0, v0, scratch);
2652 __ Push(key->value()); 2688 PushOperand(key->value());
2653 2689
2654 // Stack here: 2690 // Stack here:
2655 // - home_object 2691 // - home_object
2656 // - this (receiver) 2692 // - this (receiver)
2657 // - this (receiver) <-- LoadFromSuper will pop here and below. 2693 // - this (receiver) <-- LoadFromSuper will pop here and below.
2658 // - home_object 2694 // - home_object
2659 // - key 2695 // - key
2660 __ CallRuntime(Runtime::kLoadFromSuper); 2696 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2661 2697
2662 // Replace home_object with target function. 2698 // Replace home_object with target function.
2663 __ sd(v0, MemOperand(sp, kPointerSize)); 2699 __ sd(v0, MemOperand(sp, kPointerSize));
2664 2700
2665 // Stack here: 2701 // Stack here:
2666 // - target function 2702 // - target function
2667 // - this (receiver) 2703 // - this (receiver)
2668 EmitCall(expr); 2704 EmitCall(expr);
2669 } 2705 }
2670 2706
2671 2707
2672 // Code common for calls using the IC. 2708 // Code common for calls using the IC.
2673 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2709 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2674 Expression* key) { 2710 Expression* key) {
2675 // Load the key. 2711 // Load the key.
2676 VisitForAccumulatorValue(key); 2712 VisitForAccumulatorValue(key);
2677 2713
2678 Expression* callee = expr->expression(); 2714 Expression* callee = expr->expression();
2679 2715
2680 // Load the function from the receiver. 2716 // Load the function from the receiver.
2681 DCHECK(callee->IsProperty()); 2717 DCHECK(callee->IsProperty());
2682 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2718 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2683 __ Move(LoadDescriptor::NameRegister(), v0); 2719 __ Move(LoadDescriptor::NameRegister(), v0);
2684 EmitKeyedPropertyLoad(callee->AsProperty()); 2720 EmitKeyedPropertyLoad(callee->AsProperty());
2685 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2721 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2686 2722
2687 // Push the target function under the receiver. 2723 // Push the target function under the receiver.
2688 __ ld(at, MemOperand(sp, 0)); 2724 __ ld(at, MemOperand(sp, 0));
2689 __ push(at); 2725 PushOperand(at);
2690 __ sd(v0, MemOperand(sp, kPointerSize)); 2726 __ sd(v0, MemOperand(sp, kPointerSize));
2691 2727
2692 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2728 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2693 } 2729 }
2694 2730
2695 2731
2696 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2732 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2697 Expression* callee = expr->expression(); 2733 Expression* callee = expr->expression();
2698 DCHECK(callee->IsProperty()); 2734 DCHECK(callee->IsProperty());
2699 Property* prop = callee->AsProperty(); 2735 Property* prop = callee->AsProperty();
2700 DCHECK(prop->IsSuperAccess()); 2736 DCHECK(prop->IsSuperAccess());
2701 2737
2702 SetExpressionPosition(prop); 2738 SetExpressionPosition(prop);
2703 // Load the function from the receiver. 2739 // Load the function from the receiver.
2704 const Register scratch = a1; 2740 const Register scratch = a1;
2705 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2741 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2706 VisitForAccumulatorValue(super_ref->home_object()); 2742 VisitForAccumulatorValue(super_ref->home_object());
2707 __ Move(scratch, v0); 2743 __ Move(scratch, v0);
2708 VisitForAccumulatorValue(super_ref->this_var()); 2744 VisitForAccumulatorValue(super_ref->this_var());
2709 __ Push(scratch, v0, v0, scratch); 2745 PushOperands(scratch, v0, v0, scratch);
2710 VisitForStackValue(prop->key()); 2746 VisitForStackValue(prop->key());
2711 2747
2712 // Stack here: 2748 // Stack here:
2713 // - home_object 2749 // - home_object
2714 // - this (receiver) 2750 // - this (receiver)
2715 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2751 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2716 // - home_object 2752 // - home_object
2717 // - key 2753 // - key
2718 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2754 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2719 2755
2720 // Replace home_object with target function. 2756 // Replace home_object with target function.
2721 __ sd(v0, MemOperand(sp, kPointerSize)); 2757 __ sd(v0, MemOperand(sp, kPointerSize));
2722 2758
2723 // Stack here: 2759 // Stack here:
2724 // - target function 2760 // - target function
2725 // - this (receiver) 2761 // - this (receiver)
2726 EmitCall(expr); 2762 EmitCall(expr);
2727 } 2763 }
2728 2764
(...skipping 18 matching lines...) Expand all
2747 EmitProfilingCounterHandlingForReturnSequence(true); 2783 EmitProfilingCounterHandlingForReturnSequence(true);
2748 } 2784 }
2749 Handle<Code> ic = 2785 Handle<Code> ic =
2750 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2786 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2751 .code(); 2787 .code();
2752 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); 2788 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
2753 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2789 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2754 // Don't assign a type feedback id to the IC, since type feedback is provided 2790 // Don't assign a type feedback id to the IC, since type feedback is provided
2755 // by the vector above. 2791 // by the vector above.
2756 CallIC(ic); 2792 CallIC(ic);
2793 OperandStackDepthDecrement(arg_count + 1);
2794
2757 RecordJSReturnSite(expr); 2795 RecordJSReturnSite(expr);
2758 // Restore context register. 2796 // Restore context register.
2759 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2797 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2760 context()->DropAndPlug(1, v0); 2798 context()->DropAndPlug(1, v0);
2761 } 2799 }
2762 2800
2763 2801
2764 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2802 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2765 // a6: copy of the first argument or undefined if it doesn't exist. 2803 // a6: copy of the first argument or undefined if it doesn't exist.
2766 if (arg_count > 0) { 2804 if (arg_count > 0) {
(...skipping 26 matching lines...) Expand all
2793 SetExpressionPosition(callee); 2831 SetExpressionPosition(callee);
2794 // Generate code for loading from variables potentially shadowed by 2832 // Generate code for loading from variables potentially shadowed by
2795 // eval-introduced variables. 2833 // eval-introduced variables.
2796 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2834 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2797 2835
2798 __ bind(&slow); 2836 __ bind(&slow);
2799 // Call the runtime to find the function to call (returned in v0) 2837 // Call the runtime to find the function to call (returned in v0)
2800 // and the object holding it (returned in v1). 2838 // and the object holding it (returned in v1).
2801 __ Push(callee->name()); 2839 __ Push(callee->name());
2802 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2840 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2803 __ Push(v0, v1); // Function, receiver. 2841 PushOperands(v0, v1); // Function, receiver.
2804 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2842 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2805 2843
2806 // If fast case code has been generated, emit code to push the 2844 // If fast case code has been generated, emit code to push the
2807 // function and receiver and have the slow path jump around this 2845 // function and receiver and have the slow path jump around this
2808 // code. 2846 // code.
2809 if (done.is_linked()) { 2847 if (done.is_linked()) {
2810 Label call; 2848 Label call;
2811 __ Branch(&call); 2849 __ Branch(&call);
2812 __ bind(&done); 2850 __ bind(&done);
2813 // Push function. 2851 // Push function.
2814 __ push(v0); 2852 __ push(v0);
2815 // The receiver is implicitly the global receiver. Indicate this 2853 // The receiver is implicitly the global receiver. Indicate this
2816 // by passing the hole to the call function stub. 2854 // by passing the hole to the call function stub.
2817 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); 2855 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
2818 __ push(a1); 2856 __ push(a1);
2819 __ bind(&call); 2857 __ bind(&call);
2820 } 2858 }
2821 } else { 2859 } else {
2822 VisitForStackValue(callee); 2860 VisitForStackValue(callee);
2823 // refEnv.WithBaseObject() 2861 // refEnv.WithBaseObject()
2824 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 2862 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
2825 __ push(a2); // Reserved receiver slot. 2863 PushOperand(a2); // Reserved receiver slot.
2826 } 2864 }
2827 } 2865 }
2828 2866
2829 2867
2830 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2868 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2831 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2869 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2832 // to resolve the function we need to call. Then we call the resolved 2870 // to resolve the function we need to call. Then we call the resolved
2833 // function using the given arguments. 2871 // function using the given arguments.
2834 ZoneList<Expression*>* args = expr->arguments(); 2872 ZoneList<Expression*>* args = expr->arguments();
2835 int arg_count = args->length(); 2873 int arg_count = args->length();
(...skipping 14 matching lines...) Expand all
2850 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2888 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2851 2889
2852 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2890 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2853 // Record source position for debugger. 2891 // Record source position for debugger.
2854 SetCallPosition(expr); 2892 SetCallPosition(expr);
2855 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2893 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2856 __ li(a0, Operand(arg_count)); 2894 __ li(a0, Operand(arg_count));
2857 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2895 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2858 expr->tail_call_mode()), 2896 expr->tail_call_mode()),
2859 RelocInfo::CODE_TARGET); 2897 RelocInfo::CODE_TARGET);
2898 OperandStackDepthDecrement(arg_count + 1);
2860 RecordJSReturnSite(expr); 2899 RecordJSReturnSite(expr);
2861 // Restore context register. 2900 // Restore context register.
2862 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2901 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2863 context()->DropAndPlug(1, v0); 2902 context()->DropAndPlug(1, v0);
2864 } 2903 }
2865 2904
2866 2905
2867 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2906 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2868 Comment cmnt(masm_, "[ CallNew"); 2907 Comment cmnt(masm_, "[ CallNew");
2869 // According to ECMA-262, section 11.2.2, page 44, the function 2908 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2890 // Load function and argument count into a1 and a0. 2929 // Load function and argument count into a1 and a0.
2891 __ li(a0, Operand(arg_count)); 2930 __ li(a0, Operand(arg_count));
2892 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); 2931 __ ld(a1, MemOperand(sp, arg_count * kPointerSize));
2893 2932
2894 // Record call targets in unoptimized code. 2933 // Record call targets in unoptimized code.
2895 __ EmitLoadTypeFeedbackVector(a2); 2934 __ EmitLoadTypeFeedbackVector(a2);
2896 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2935 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
2897 2936
2898 CallConstructStub stub(isolate()); 2937 CallConstructStub stub(isolate());
2899 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2938 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2939 OperandStackDepthDecrement(arg_count + 1);
2900 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2940 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2901 // Restore context register. 2941 // Restore context register.
2902 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2942 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2903 context()->Plug(v0); 2943 context()->Plug(v0);
2904 } 2944 }
2905 2945
2906 2946
2907 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2947 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2908 SuperCallReference* super_call_ref = 2948 SuperCallReference* super_call_ref =
2909 expr->expression()->AsSuperCallReference(); 2949 expr->expression()->AsSuperCallReference();
2910 DCHECK_NOT_NULL(super_call_ref); 2950 DCHECK_NOT_NULL(super_call_ref);
2911 2951
2912 // Push the super constructor target on the stack (may be null, 2952 // Push the super constructor target on the stack (may be null,
2913 // but the Construct builtin can deal with that properly). 2953 // but the Construct builtin can deal with that properly).
2914 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2954 VisitForAccumulatorValue(super_call_ref->this_function_var());
2915 __ AssertFunction(result_register()); 2955 __ AssertFunction(result_register());
2916 __ ld(result_register(), 2956 __ ld(result_register(),
2917 FieldMemOperand(result_register(), HeapObject::kMapOffset)); 2957 FieldMemOperand(result_register(), HeapObject::kMapOffset));
2918 __ ld(result_register(), 2958 __ ld(result_register(),
2919 FieldMemOperand(result_register(), Map::kPrototypeOffset)); 2959 FieldMemOperand(result_register(), Map::kPrototypeOffset));
2920 __ Push(result_register()); 2960 PushOperand(result_register());
2921 2961
2922 // Push the arguments ("left-to-right") on the stack. 2962 // Push the arguments ("left-to-right") on the stack.
2923 ZoneList<Expression*>* args = expr->arguments(); 2963 ZoneList<Expression*>* args = expr->arguments();
2924 int arg_count = args->length(); 2964 int arg_count = args->length();
2925 for (int i = 0; i < arg_count; i++) { 2965 for (int i = 0; i < arg_count; i++) {
2926 VisitForStackValue(args->at(i)); 2966 VisitForStackValue(args->at(i));
2927 } 2967 }
2928 2968
2929 // Call the construct call builtin that handles allocation and 2969 // Call the construct call builtin that handles allocation and
2930 // constructor invocation. 2970 // constructor invocation.
2931 SetConstructCallPosition(expr); 2971 SetConstructCallPosition(expr);
2932 2972
2933 // Load new target into a3. 2973 // Load new target into a3.
2934 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2974 VisitForAccumulatorValue(super_call_ref->new_target_var());
2935 __ mov(a3, result_register()); 2975 __ mov(a3, result_register());
2936 2976
2937 // Load function and argument count into a1 and a0. 2977 // Load function and argument count into a1 and a0.
2938 __ li(a0, Operand(arg_count)); 2978 __ li(a0, Operand(arg_count));
2939 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); 2979 __ ld(a1, MemOperand(sp, arg_count * kPointerSize));
2940 2980
2941 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2981 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2982 OperandStackDepthDecrement(arg_count + 1);
2942 2983
2943 RecordJSReturnSite(expr); 2984 RecordJSReturnSite(expr);
2944 2985
2945 // Restore context register. 2986 // Restore context register.
2946 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2987 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2947 context()->Plug(v0); 2988 context()->Plug(v0);
2948 } 2989 }
2949 2990
2950 2991
2951 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2992 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
3154 ZoneList<Expression*>* args = expr->arguments(); 3195 ZoneList<Expression*>* args = expr->arguments();
3155 DCHECK_EQ(3, args->length()); 3196 DCHECK_EQ(3, args->length());
3156 3197
3157 Register string = v0; 3198 Register string = v0;
3158 Register index = a1; 3199 Register index = a1;
3159 Register value = a2; 3200 Register value = a2;
3160 3201
3161 VisitForStackValue(args->at(0)); // index 3202 VisitForStackValue(args->at(0)); // index
3162 VisitForStackValue(args->at(1)); // value 3203 VisitForStackValue(args->at(1)); // value
3163 VisitForAccumulatorValue(args->at(2)); // string 3204 VisitForAccumulatorValue(args->at(2)); // string
3164 __ Pop(index, value); 3205 PopOperands(index, value);
3165 3206
3166 if (FLAG_debug_code) { 3207 if (FLAG_debug_code) {
3167 __ SmiTst(value, at); 3208 __ SmiTst(value, at);
3168 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); 3209 __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
3169 __ SmiTst(index, at); 3210 __ SmiTst(index, at);
3170 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); 3211 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
3171 __ SmiUntag(index, index); 3212 __ SmiUntag(index, index);
3172 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3213 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3173 Register scratch = t1; 3214 Register scratch = t1;
3174 __ EmitSeqStringSetCharCheck( 3215 __ EmitSeqStringSetCharCheck(
(...skipping 16 matching lines...) Expand all
3191 ZoneList<Expression*>* args = expr->arguments(); 3232 ZoneList<Expression*>* args = expr->arguments();
3192 DCHECK_EQ(3, args->length()); 3233 DCHECK_EQ(3, args->length());
3193 3234
3194 Register string = v0; 3235 Register string = v0;
3195 Register index = a1; 3236 Register index = a1;
3196 Register value = a2; 3237 Register value = a2;
3197 3238
3198 VisitForStackValue(args->at(0)); // index 3239 VisitForStackValue(args->at(0)); // index
3199 VisitForStackValue(args->at(1)); // value 3240 VisitForStackValue(args->at(1)); // value
3200 VisitForAccumulatorValue(args->at(2)); // string 3241 VisitForAccumulatorValue(args->at(2)); // string
3201 __ Pop(index, value); 3242 PopOperands(index, value);
3202 3243
3203 if (FLAG_debug_code) { 3244 if (FLAG_debug_code) {
3204 __ SmiTst(value, at); 3245 __ SmiTst(value, at);
3205 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); 3246 __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
3206 __ SmiTst(index, at); 3247 __ SmiTst(index, at);
3207 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); 3248 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
3208 __ SmiUntag(index, index); 3249 __ SmiUntag(index, index);
3209 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3250 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3210 Register scratch = t1; 3251 Register scratch = t1;
3211 __ EmitSeqStringSetCharCheck( 3252 __ EmitSeqStringSetCharCheck(
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 DCHECK(args->length() == 2); 3307 DCHECK(args->length() == 2);
3267 3308
3268 VisitForStackValue(args->at(0)); 3309 VisitForStackValue(args->at(0));
3269 VisitForAccumulatorValue(args->at(1)); 3310 VisitForAccumulatorValue(args->at(1));
3270 __ mov(a0, result_register()); 3311 __ mov(a0, result_register());
3271 3312
3272 Register object = a1; 3313 Register object = a1;
3273 Register index = a0; 3314 Register index = a0;
3274 Register result = v0; 3315 Register result = v0;
3275 3316
3276 __ pop(object); 3317 PopOperand(object);
3277 3318
3278 Label need_conversion; 3319 Label need_conversion;
3279 Label index_out_of_range; 3320 Label index_out_of_range;
3280 Label done; 3321 Label done;
3281 StringCharCodeAtGenerator generator(object, 3322 StringCharCodeAtGenerator generator(object,
3282 index, 3323 index,
3283 result, 3324 result,
3284 &need_conversion, 3325 &need_conversion,
3285 &need_conversion, 3326 &need_conversion,
3286 &index_out_of_range, 3327 &index_out_of_range,
(...skipping 27 matching lines...) Expand all
3314 3355
3315 VisitForStackValue(args->at(0)); 3356 VisitForStackValue(args->at(0));
3316 VisitForAccumulatorValue(args->at(1)); 3357 VisitForAccumulatorValue(args->at(1));
3317 __ mov(a0, result_register()); 3358 __ mov(a0, result_register());
3318 3359
3319 Register object = a1; 3360 Register object = a1;
3320 Register index = a0; 3361 Register index = a0;
3321 Register scratch = a3; 3362 Register scratch = a3;
3322 Register result = v0; 3363 Register result = v0;
3323 3364
3324 __ pop(object); 3365 PopOperand(object);
3325 3366
3326 Label need_conversion; 3367 Label need_conversion;
3327 Label index_out_of_range; 3368 Label index_out_of_range;
3328 Label done; 3369 Label done;
3329 StringCharAtGenerator generator(object, 3370 StringCharAtGenerator generator(object,
3330 index, 3371 index,
3331 scratch, 3372 scratch,
3332 result, 3373 result,
3333 &need_conversion, 3374 &need_conversion,
3334 &need_conversion, 3375 &need_conversion,
(...skipping 29 matching lines...) Expand all
3364 for (Expression* const arg : *args) { 3405 for (Expression* const arg : *args) {
3365 VisitForStackValue(arg); 3406 VisitForStackValue(arg);
3366 } 3407 }
3367 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3408 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3368 // Move target to a1. 3409 // Move target to a1.
3369 int const argc = args->length() - 2; 3410 int const argc = args->length() - 2;
3370 __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize)); 3411 __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize));
3371 // Call the target. 3412 // Call the target.
3372 __ li(a0, Operand(argc)); 3413 __ li(a0, Operand(argc));
3373 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3414 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3415 OperandStackDepthDecrement(argc + 1);
3374 // Restore context register. 3416 // Restore context register.
3375 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3417 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3376 // Discard the function left on TOS. 3418 // Discard the function left on TOS.
3377 context()->DropAndPlug(1, v0); 3419 context()->DropAndPlug(1, v0);
3378 } 3420 }
3379 3421
3380 3422
3381 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3423 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3382 ZoneList<Expression*>* args = expr->arguments(); 3424 ZoneList<Expression*>* args = expr->arguments();
3383 VisitForAccumulatorValue(args->at(0)); 3425 VisitForAccumulatorValue(args->at(0));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3449 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex); 3491 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex);
3450 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 3492 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
3451 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 3493 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset));
3452 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); 3494 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset));
3453 __ sd(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); 3495 __ sd(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset));
3454 __ sd(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); 3496 __ sd(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset));
3455 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3497 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3456 __ jmp(&done); 3498 __ jmp(&done);
3457 3499
3458 __ bind(&runtime); 3500 __ bind(&runtime);
3459 __ CallRuntime(Runtime::kCreateIterResultObject); 3501 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3460 3502
3461 __ bind(&done); 3503 __ bind(&done);
3462 context()->Plug(v0); 3504 context()->Plug(v0);
3463 } 3505 }
3464 3506
3465 3507
3466 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3508 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3467 // Push undefined as the receiver. 3509 // Push undefined as the receiver.
3468 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 3510 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
3469 __ push(v0); 3511 PushOperand(v0);
3470 3512
3471 __ LoadNativeContextSlot(expr->context_index(), v0); 3513 __ LoadNativeContextSlot(expr->context_index(), v0);
3472 } 3514 }
3473 3515
3474 3516
3475 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3517 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3476 ZoneList<Expression*>* args = expr->arguments(); 3518 ZoneList<Expression*>* args = expr->arguments();
3477 int arg_count = args->length(); 3519 int arg_count = args->length();
3478 3520
3479 SetCallPosition(expr); 3521 SetCallPosition(expr);
3480 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 3522 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
3481 __ li(a0, Operand(arg_count)); 3523 __ li(a0, Operand(arg_count));
3482 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3524 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3483 RelocInfo::CODE_TARGET); 3525 RelocInfo::CODE_TARGET);
3526 OperandStackDepthDecrement(arg_count + 1);
3484 } 3527 }
3485 3528
3486 3529
3487 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3530 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3488 ZoneList<Expression*>* args = expr->arguments(); 3531 ZoneList<Expression*>* args = expr->arguments();
3489 int arg_count = args->length(); 3532 int arg_count = args->length();
3490 3533
3491 if (expr->is_jsruntime()) { 3534 if (expr->is_jsruntime()) {
3492 Comment cmnt(masm_, "[ CallRuntime"); 3535 Comment cmnt(masm_, "[ CallRuntime");
3493 EmitLoadJSRuntimeFunction(expr); 3536 EmitLoadJSRuntimeFunction(expr);
3494 3537
3495 // Push the target function under the receiver. 3538 // Push the target function under the receiver.
3496 __ ld(at, MemOperand(sp, 0)); 3539 __ ld(at, MemOperand(sp, 0));
3497 __ push(at); 3540 PushOperand(at);
3498 __ sd(v0, MemOperand(sp, kPointerSize)); 3541 __ sd(v0, MemOperand(sp, kPointerSize));
3499 3542
3500 // Push the arguments ("left-to-right"). 3543 // Push the arguments ("left-to-right").
3501 for (int i = 0; i < arg_count; i++) { 3544 for (int i = 0; i < arg_count; i++) {
3502 VisitForStackValue(args->at(i)); 3545 VisitForStackValue(args->at(i));
3503 } 3546 }
3504 3547
3505 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3548 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3506 EmitCallJSRuntimeFunction(expr); 3549 EmitCallJSRuntimeFunction(expr);
3507 3550
(...skipping 14 matching lines...) Expand all
3522 default: { 3565 default: {
3523 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3566 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3524 // Push the arguments ("left-to-right"). 3567 // Push the arguments ("left-to-right").
3525 for (int i = 0; i < arg_count; i++) { 3568 for (int i = 0; i < arg_count; i++) {
3526 VisitForStackValue(args->at(i)); 3569 VisitForStackValue(args->at(i));
3527 } 3570 }
3528 3571
3529 // Call the C runtime function. 3572 // Call the C runtime function.
3530 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3573 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3531 __ CallRuntime(expr->function(), arg_count); 3574 __ CallRuntime(expr->function(), arg_count);
3575 OperandStackDepthDecrement(arg_count);
3532 context()->Plug(v0); 3576 context()->Plug(v0);
3533 } 3577 }
3534 } 3578 }
3535 } 3579 }
3536 } 3580 }
3537 3581
3538 3582
3539 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3583 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3540 switch (expr->op()) { 3584 switch (expr->op()) {
3541 case Token::DELETE: { 3585 case Token::DELETE: {
3542 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3586 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3543 Property* property = expr->expression()->AsProperty(); 3587 Property* property = expr->expression()->AsProperty();
3544 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3588 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3545 3589
3546 if (property != NULL) { 3590 if (property != NULL) {
3547 VisitForStackValue(property->obj()); 3591 VisitForStackValue(property->obj());
3548 VisitForStackValue(property->key()); 3592 VisitForStackValue(property->key());
3549 __ CallRuntime(is_strict(language_mode()) 3593 CallRuntimeWithOperands(is_strict(language_mode())
3550 ? Runtime::kDeleteProperty_Strict 3594 ? Runtime::kDeleteProperty_Strict
3551 : Runtime::kDeleteProperty_Sloppy); 3595 : Runtime::kDeleteProperty_Sloppy);
3552 context()->Plug(v0); 3596 context()->Plug(v0);
3553 } else if (proxy != NULL) { 3597 } else if (proxy != NULL) {
3554 Variable* var = proxy->var(); 3598 Variable* var = proxy->var();
3555 // Delete of an unqualified identifier is disallowed in strict mode but 3599 // Delete of an unqualified identifier is disallowed in strict mode but
3556 // "delete this" is allowed. 3600 // "delete this" is allowed.
3557 bool is_this = var->HasThisName(isolate()); 3601 bool is_this = var->HasThisName(isolate());
3558 DCHECK(is_sloppy(language_mode()) || is_this); 3602 DCHECK(is_sloppy(language_mode()) || is_this);
3559 if (var->IsUnallocatedOrGlobalSlot()) { 3603 if (var->IsUnallocatedOrGlobalSlot()) {
3560 __ LoadGlobalObject(a2); 3604 __ LoadGlobalObject(a2);
3561 __ li(a1, Operand(var->name())); 3605 __ li(a1, Operand(var->name()));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3608 // We handle value contexts explicitly rather than simply visiting 3652 // We handle value contexts explicitly rather than simply visiting
3609 // for control and plugging the control flow into the context, 3653 // for control and plugging the control flow into the context,
3610 // because we need to prepare a pair of extra administrative AST ids 3654 // because we need to prepare a pair of extra administrative AST ids
3611 // for the optimizing compiler. 3655 // for the optimizing compiler.
3612 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3656 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3613 Label materialize_true, materialize_false, done; 3657 Label materialize_true, materialize_false, done;
3614 VisitForControl(expr->expression(), 3658 VisitForControl(expr->expression(),
3615 &materialize_false, 3659 &materialize_false,
3616 &materialize_true, 3660 &materialize_true,
3617 &materialize_true); 3661 &materialize_true);
3662 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3618 __ bind(&materialize_true); 3663 __ bind(&materialize_true);
3619 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3664 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3620 __ LoadRoot(v0, Heap::kTrueValueRootIndex); 3665 __ LoadRoot(v0, Heap::kTrueValueRootIndex);
3621 if (context()->IsStackValue()) __ push(v0); 3666 if (context()->IsStackValue()) __ push(v0);
3622 __ jmp(&done); 3667 __ jmp(&done);
3623 __ bind(&materialize_false); 3668 __ bind(&materialize_false);
3624 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3669 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
3625 __ LoadRoot(v0, Heap::kFalseValueRootIndex); 3670 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
3626 if (context()->IsStackValue()) __ push(v0); 3671 if (context()->IsStackValue()) __ push(v0);
3627 __ bind(&done); 3672 __ bind(&done);
(...skipping 30 matching lines...) Expand all
3658 3703
3659 // Evaluate expression and get value. 3704 // Evaluate expression and get value.
3660 if (assign_type == VARIABLE) { 3705 if (assign_type == VARIABLE) {
3661 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3706 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3662 AccumulatorValueContext context(this); 3707 AccumulatorValueContext context(this);
3663 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3708 EmitVariableLoad(expr->expression()->AsVariableProxy());
3664 } else { 3709 } else {
3665 // Reserve space for result of postfix operation. 3710 // Reserve space for result of postfix operation.
3666 if (expr->is_postfix() && !context()->IsEffect()) { 3711 if (expr->is_postfix() && !context()->IsEffect()) {
3667 __ li(at, Operand(Smi::FromInt(0))); 3712 __ li(at, Operand(Smi::FromInt(0)));
3668 __ push(at); 3713 PushOperand(at);
3669 } 3714 }
3670 switch (assign_type) { 3715 switch (assign_type) {
3671 case NAMED_PROPERTY: { 3716 case NAMED_PROPERTY: {
3672 // Put the object both on the stack and in the register. 3717 // Put the object both on the stack and in the register.
3673 VisitForStackValue(prop->obj()); 3718 VisitForStackValue(prop->obj());
3674 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 3719 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
3675 EmitNamedPropertyLoad(prop); 3720 EmitNamedPropertyLoad(prop);
3676 break; 3721 break;
3677 } 3722 }
3678 3723
3679 case NAMED_SUPER_PROPERTY: { 3724 case NAMED_SUPER_PROPERTY: {
3680 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3725 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3681 VisitForAccumulatorValue( 3726 VisitForAccumulatorValue(
3682 prop->obj()->AsSuperPropertyReference()->home_object()); 3727 prop->obj()->AsSuperPropertyReference()->home_object());
3683 __ Push(result_register()); 3728 PushOperand(result_register());
3684 const Register scratch = a1; 3729 const Register scratch = a1;
3685 __ ld(scratch, MemOperand(sp, kPointerSize)); 3730 __ ld(scratch, MemOperand(sp, kPointerSize));
3686 __ Push(scratch, result_register()); 3731 PushOperands(scratch, result_register());
3687 EmitNamedSuperPropertyLoad(prop); 3732 EmitNamedSuperPropertyLoad(prop);
3688 break; 3733 break;
3689 } 3734 }
3690 3735
3691 case KEYED_SUPER_PROPERTY: { 3736 case KEYED_SUPER_PROPERTY: {
3692 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3737 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3693 VisitForAccumulatorValue( 3738 VisitForAccumulatorValue(
3694 prop->obj()->AsSuperPropertyReference()->home_object()); 3739 prop->obj()->AsSuperPropertyReference()->home_object());
3695 const Register scratch = a1; 3740 const Register scratch = a1;
3696 const Register scratch1 = a4; 3741 const Register scratch1 = a4;
3697 __ Move(scratch, result_register()); 3742 __ Move(scratch, result_register());
3698 VisitForAccumulatorValue(prop->key()); 3743 VisitForAccumulatorValue(prop->key());
3699 __ Push(scratch, result_register()); 3744 PushOperands(scratch, result_register());
3700 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize)); 3745 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize));
3701 __ Push(scratch1, scratch, result_register()); 3746 PushOperands(scratch1, scratch, result_register());
3702 EmitKeyedSuperPropertyLoad(prop); 3747 EmitKeyedSuperPropertyLoad(prop);
3703 break; 3748 break;
3704 } 3749 }
3705 3750
3706 case KEYED_PROPERTY: { 3751 case KEYED_PROPERTY: {
3707 VisitForStackValue(prop->obj()); 3752 VisitForStackValue(prop->obj());
3708 VisitForStackValue(prop->key()); 3753 VisitForStackValue(prop->key());
3709 __ ld(LoadDescriptor::ReceiverRegister(), 3754 __ ld(LoadDescriptor::ReceiverRegister(),
3710 MemOperand(sp, 1 * kPointerSize)); 3755 MemOperand(sp, 1 * kPointerSize));
3711 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); 3756 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3779 } 3824 }
3780 3825
3781 // Save result for postfix expressions. 3826 // Save result for postfix expressions.
3782 if (expr->is_postfix()) { 3827 if (expr->is_postfix()) {
3783 if (!context()->IsEffect()) { 3828 if (!context()->IsEffect()) {
3784 // Save the result on the stack. If we have a named or keyed property 3829 // Save the result on the stack. If we have a named or keyed property
3785 // we store the result under the receiver that is currently on top 3830 // we store the result under the receiver that is currently on top
3786 // of the stack. 3831 // of the stack.
3787 switch (assign_type) { 3832 switch (assign_type) {
3788 case VARIABLE: 3833 case VARIABLE:
3789 __ push(v0); 3834 PushOperand(v0);
3790 break; 3835 break;
3791 case NAMED_PROPERTY: 3836 case NAMED_PROPERTY:
3792 __ sd(v0, MemOperand(sp, kPointerSize)); 3837 __ sd(v0, MemOperand(sp, kPointerSize));
3793 break; 3838 break;
3794 case NAMED_SUPER_PROPERTY: 3839 case NAMED_SUPER_PROPERTY:
3795 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); 3840 __ sd(v0, MemOperand(sp, 2 * kPointerSize));
3796 break; 3841 break;
3797 case KEYED_PROPERTY: 3842 case KEYED_PROPERTY:
3798 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); 3843 __ sd(v0, MemOperand(sp, 2 * kPointerSize));
3799 break; 3844 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3837 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3882 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3838 Token::ASSIGN, expr->CountSlot()); 3883 Token::ASSIGN, expr->CountSlot());
3839 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3884 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3840 context()->Plug(v0); 3885 context()->Plug(v0);
3841 } 3886 }
3842 break; 3887 break;
3843 case NAMED_PROPERTY: { 3888 case NAMED_PROPERTY: {
3844 __ mov(StoreDescriptor::ValueRegister(), result_register()); 3889 __ mov(StoreDescriptor::ValueRegister(), result_register());
3845 __ li(StoreDescriptor::NameRegister(), 3890 __ li(StoreDescriptor::NameRegister(),
3846 Operand(prop->key()->AsLiteral()->value())); 3891 Operand(prop->key()->AsLiteral()->value()));
3847 __ pop(StoreDescriptor::ReceiverRegister()); 3892 PopOperand(StoreDescriptor::ReceiverRegister());
3848 EmitLoadStoreICSlot(expr->CountSlot()); 3893 EmitLoadStoreICSlot(expr->CountSlot());
3849 CallStoreIC(); 3894 CallStoreIC();
3850 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3895 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3851 if (expr->is_postfix()) { 3896 if (expr->is_postfix()) {
3852 if (!context()->IsEffect()) { 3897 if (!context()->IsEffect()) {
3853 context()->PlugTOS(); 3898 context()->PlugTOS();
3854 } 3899 }
3855 } else { 3900 } else {
3856 context()->Plug(v0); 3901 context()->Plug(v0);
3857 } 3902 }
(...skipping 16 matching lines...) Expand all
3874 if (!context()->IsEffect()) { 3919 if (!context()->IsEffect()) {
3875 context()->PlugTOS(); 3920 context()->PlugTOS();
3876 } 3921 }
3877 } else { 3922 } else {
3878 context()->Plug(v0); 3923 context()->Plug(v0);
3879 } 3924 }
3880 break; 3925 break;
3881 } 3926 }
3882 case KEYED_PROPERTY: { 3927 case KEYED_PROPERTY: {
3883 __ mov(StoreDescriptor::ValueRegister(), result_register()); 3928 __ mov(StoreDescriptor::ValueRegister(), result_register());
3884 __ Pop(StoreDescriptor::ReceiverRegister(), 3929 PopOperands(StoreDescriptor::ReceiverRegister(),
3885 StoreDescriptor::NameRegister()); 3930 StoreDescriptor::NameRegister());
3886 Handle<Code> ic = 3931 Handle<Code> ic =
3887 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3932 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3888 EmitLoadStoreICSlot(expr->CountSlot()); 3933 EmitLoadStoreICSlot(expr->CountSlot());
3889 CallIC(ic); 3934 CallIC(ic);
3890 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3935 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3891 if (expr->is_postfix()) { 3936 if (expr->is_postfix()) {
3892 if (!context()->IsEffect()) { 3937 if (!context()->IsEffect()) {
3893 context()->PlugTOS(); 3938 context()->PlugTOS();
3894 } 3939 }
3895 } else { 3940 } else {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3997 Label* if_false = NULL; 4042 Label* if_false = NULL;
3998 Label* fall_through = NULL; 4043 Label* fall_through = NULL;
3999 context()->PrepareTest(&materialize_true, &materialize_false, 4044 context()->PrepareTest(&materialize_true, &materialize_false,
4000 &if_true, &if_false, &fall_through); 4045 &if_true, &if_false, &fall_through);
4001 4046
4002 Token::Value op = expr->op(); 4047 Token::Value op = expr->op();
4003 VisitForStackValue(expr->left()); 4048 VisitForStackValue(expr->left());
4004 switch (op) { 4049 switch (op) {
4005 case Token::IN: 4050 case Token::IN:
4006 VisitForStackValue(expr->right()); 4051 VisitForStackValue(expr->right());
4007 __ CallRuntime(Runtime::kHasProperty); 4052 CallRuntimeWithOperands(Runtime::kHasProperty);
4008 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4053 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4009 __ LoadRoot(a4, Heap::kTrueValueRootIndex); 4054 __ LoadRoot(a4, Heap::kTrueValueRootIndex);
4010 Split(eq, v0, Operand(a4), if_true, if_false, fall_through); 4055 Split(eq, v0, Operand(a4), if_true, if_false, fall_through);
4011 break; 4056 break;
4012 4057
4013 case Token::INSTANCEOF: { 4058 case Token::INSTANCEOF: {
4014 VisitForAccumulatorValue(expr->right()); 4059 VisitForAccumulatorValue(expr->right());
4015 __ mov(a0, result_register()); 4060 __ mov(a0, result_register());
4016 __ pop(a1); 4061 PopOperand(a1);
4017 InstanceOfStub stub(isolate()); 4062 InstanceOfStub stub(isolate());
4018 __ CallStub(&stub); 4063 __ CallStub(&stub);
4019 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4064 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4020 __ LoadRoot(a4, Heap::kTrueValueRootIndex); 4065 __ LoadRoot(a4, Heap::kTrueValueRootIndex);
4021 Split(eq, v0, Operand(a4), if_true, if_false, fall_through); 4066 Split(eq, v0, Operand(a4), if_true, if_false, fall_through);
4022 break; 4067 break;
4023 } 4068 }
4024 4069
4025 default: { 4070 default: {
4026 VisitForAccumulatorValue(expr->right()); 4071 VisitForAccumulatorValue(expr->right());
4027 Condition cc = CompareIC::ComputeCondition(op); 4072 Condition cc = CompareIC::ComputeCondition(op);
4028 __ mov(a0, result_register()); 4073 __ mov(a0, result_register());
4029 __ pop(a1); 4074 PopOperand(a1);
4030 4075
4031 bool inline_smi_code = ShouldInlineSmiCase(op); 4076 bool inline_smi_code = ShouldInlineSmiCase(op);
4032 JumpPatchSite patch_site(masm_); 4077 JumpPatchSite patch_site(masm_);
4033 if (inline_smi_code) { 4078 if (inline_smi_code) {
4034 Label slow_case; 4079 Label slow_case;
4035 __ Or(a2, a0, Operand(a1)); 4080 __ Or(a2, a0, Operand(a1));
4036 patch_site.EmitJumpIfNotSmi(a2, &slow_case); 4081 patch_site.EmitJumpIfNotSmi(a2, &slow_case);
4037 Split(cc, a1, Operand(a0), if_true, if_false, NULL); 4082 Split(cc, a1, Operand(a0), if_true, if_false, NULL);
4038 __ bind(&slow_case); 4083 __ bind(&slow_case);
4039 } 4084 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4120 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, at); 4165 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, at);
4121 } else if (closure_scope->is_eval_scope()) { 4166 } else if (closure_scope->is_eval_scope()) {
4122 // Contexts created by a call to eval have the same closure as the 4167 // Contexts created by a call to eval have the same closure as the
4123 // context calling eval, not the anonymous closure containing the eval 4168 // context calling eval, not the anonymous closure containing the eval
4124 // code. Fetch it from the context. 4169 // code. Fetch it from the context.
4125 __ ld(at, ContextMemOperand(cp, Context::CLOSURE_INDEX)); 4170 __ ld(at, ContextMemOperand(cp, Context::CLOSURE_INDEX));
4126 } else { 4171 } else {
4127 DCHECK(closure_scope->is_function_scope()); 4172 DCHECK(closure_scope->is_function_scope());
4128 __ ld(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4173 __ ld(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4129 } 4174 }
4130 __ push(at); 4175 PushOperand(at);
4131 } 4176 }
4132 4177
4133 4178
4134 // ---------------------------------------------------------------------------- 4179 // ----------------------------------------------------------------------------
4135 // Non-local control flow support. 4180 // Non-local control flow support.
4136 4181
4137 void FullCodeGenerator::EnterFinallyBlock() { 4182 void FullCodeGenerator::EnterFinallyBlock() {
4138 DCHECK(!result_register().is(a1)); 4183 DCHECK(!result_register().is(a1));
4139 // Store pending message while executing finally block. 4184 // Store pending message while executing finally block.
4140 ExternalReference pending_message_obj = 4185 ExternalReference pending_message_obj =
4141 ExternalReference::address_of_pending_message_obj(isolate()); 4186 ExternalReference::address_of_pending_message_obj(isolate());
4142 __ li(at, Operand(pending_message_obj)); 4187 __ li(at, Operand(pending_message_obj));
4143 __ ld(a1, MemOperand(at)); 4188 __ ld(a1, MemOperand(at));
4144 __ push(a1); 4189 PushOperand(a1);
4145 4190
4146 ClearPendingMessage(); 4191 ClearPendingMessage();
4147 } 4192 }
4148 4193
4149 4194
4150 void FullCodeGenerator::ExitFinallyBlock() { 4195 void FullCodeGenerator::ExitFinallyBlock() {
4151 DCHECK(!result_register().is(a1)); 4196 DCHECK(!result_register().is(a1));
4152 // Restore pending message from stack. 4197 // Restore pending message from stack.
4153 __ pop(a1); 4198 PopOperand(a1);
4154 ExternalReference pending_message_obj = 4199 ExternalReference pending_message_obj =
4155 ExternalReference::address_of_pending_message_obj(isolate()); 4200 ExternalReference::address_of_pending_message_obj(isolate());
4156 __ li(at, Operand(pending_message_obj)); 4201 __ li(at, Operand(pending_message_obj));
4157 __ sd(a1, MemOperand(at)); 4202 __ sd(a1, MemOperand(at));
4158 } 4203 }
4159 4204
4160 4205
4161 void FullCodeGenerator::ClearPendingMessage() { 4206 void FullCodeGenerator::ClearPendingMessage() {
4162 DCHECK(!result_register().is(a1)); 4207 DCHECK(!result_register().is(a1));
4163 ExternalReference pending_message_obj = 4208 ExternalReference pending_message_obj =
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
4281 reinterpret_cast<uint64_t>( 4326 reinterpret_cast<uint64_t>(
4282 isolate->builtins()->OsrAfterStackCheck()->entry())); 4327 isolate->builtins()->OsrAfterStackCheck()->entry()));
4283 return OSR_AFTER_STACK_CHECK; 4328 return OSR_AFTER_STACK_CHECK;
4284 } 4329 }
4285 4330
4286 4331
4287 } // namespace internal 4332 } // namespace internal
4288 } // namespace v8 4333 } // namespace v8
4289 4334
4290 #endif // V8_TARGET_ARCH_MIPS64 4335 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698