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

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

Issue 1706283002: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Turn off verification. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/arm/full-codegen-arm.cc ('k') | src/full-codegen/full-codegen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 // Push(lr, fp, cp, x1); 128 // Push(lr, fp, cp, x1);
129 // Add(fp, jssp, 2 * kPointerSize); 129 // Add(fp, jssp, 2 * kPointerSize);
130 info->set_prologue_offset(masm_->pc_offset()); 130 info->set_prologue_offset(masm_->pc_offset());
131 __ Prologue(info->GeneratePreagedPrologue()); 131 __ Prologue(info->GeneratePreagedPrologue());
132 132
133 // Reserve space on the stack for locals. 133 // Reserve space on the stack for locals.
134 { Comment cmnt(masm_, "[ Allocate locals"); 134 { Comment cmnt(masm_, "[ Allocate locals");
135 int locals_count = info->scope()->num_stack_slots(); 135 int locals_count = info->scope()->num_stack_slots();
136 // Generators allocate locals, if any, in context slots. 136 // Generators allocate locals, if any, in context slots.
137 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 137 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
138 138 OperandStackDepthIncrement(locals_count);
139 if (locals_count > 0) { 139 if (locals_count > 0) {
140 if (locals_count >= 128) { 140 if (locals_count >= 128) {
141 Label ok; 141 Label ok;
142 DCHECK(jssp.Is(__ StackPointer())); 142 DCHECK(jssp.Is(__ StackPointer()));
143 __ Sub(x10, jssp, locals_count * kPointerSize); 143 __ Sub(x10, jssp, locals_count * kPointerSize);
144 __ CompareRoot(x10, Heap::kRealStackLimitRootIndex); 144 __ CompareRoot(x10, Heap::kRealStackLimitRootIndex);
145 __ B(hs, &ok); 145 __ B(hs, &ok);
146 __ CallRuntime(Runtime::kThrowStackOverflow); 146 __ CallRuntime(Runtime::kThrowStackOverflow);
147 __ Bind(&ok); 147 __ Bind(&ok);
148 } 148 }
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 __ Ret(); 463 __ Ret();
464 int32_t arg_count = info_->scope()->num_parameters() + 1; 464 int32_t arg_count = info_->scope()->num_parameters() + 1;
465 __ dc64(kXRegSize * arg_count); 465 __ dc64(kXRegSize * arg_count);
466 } 466 }
467 } 467 }
468 468
469 469
470 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 470 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
471 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 471 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
472 codegen()->GetVar(result_register(), var); 472 codegen()->GetVar(result_register(), var);
473 __ Push(result_register()); 473 codegen()->PushOperand(result_register());
474 } 474 }
475 475
476 476
477 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 477 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
478 // Root values have no side effects. 478 // Root values have no side effects.
479 } 479 }
480 480
481 481
482 void FullCodeGenerator::AccumulatorValueContext::Plug( 482 void FullCodeGenerator::AccumulatorValueContext::Plug(
483 Heap::RootListIndex index) const { 483 Heap::RootListIndex index) const {
484 __ LoadRoot(result_register(), index); 484 __ LoadRoot(result_register(), index);
485 } 485 }
486 486
487 487
488 void FullCodeGenerator::StackValueContext::Plug( 488 void FullCodeGenerator::StackValueContext::Plug(
489 Heap::RootListIndex index) const { 489 Heap::RootListIndex index) const {
490 __ LoadRoot(result_register(), index); 490 __ LoadRoot(result_register(), index);
491 __ Push(result_register()); 491 codegen()->PushOperand(result_register());
492 } 492 }
493 493
494 494
495 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 495 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
496 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, 496 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
497 false_label_); 497 false_label_);
498 if (index == Heap::kUndefinedValueRootIndex || 498 if (index == Heap::kUndefinedValueRootIndex ||
499 index == Heap::kNullValueRootIndex || 499 index == Heap::kNullValueRootIndex ||
500 index == Heap::kFalseValueRootIndex) { 500 index == Heap::kFalseValueRootIndex) {
501 if (false_label_ != fall_through_) __ B(false_label_); 501 if (false_label_ != fall_through_) __ B(false_label_);
(...skipping 12 matching lines...) Expand all
514 514
515 void FullCodeGenerator::AccumulatorValueContext::Plug( 515 void FullCodeGenerator::AccumulatorValueContext::Plug(
516 Handle<Object> lit) const { 516 Handle<Object> lit) const {
517 __ Mov(result_register(), Operand(lit)); 517 __ Mov(result_register(), Operand(lit));
518 } 518 }
519 519
520 520
521 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 521 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
522 // Immediates cannot be pushed directly. 522 // Immediates cannot be pushed directly.
523 __ Mov(result_register(), Operand(lit)); 523 __ Mov(result_register(), Operand(lit));
524 __ Push(result_register()); 524 codegen()->PushOperand(result_register());
525 } 525 }
526 526
527 527
528 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 528 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
529 codegen()->PrepareForBailoutBeforeSplit(condition(), 529 codegen()->PrepareForBailoutBeforeSplit(condition(),
530 true, 530 true,
531 true_label_, 531 true_label_,
532 false_label_); 532 false_label_);
533 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); 533 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject());
534 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 534 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
(...skipping 13 matching lines...) Expand all
548 if (true_label_ != fall_through_) __ B(true_label_); 548 if (true_label_ != fall_through_) __ B(true_label_);
549 } 549 }
550 } else { 550 } else {
551 // For simplicity we always test the accumulator register. 551 // For simplicity we always test the accumulator register.
552 __ Mov(result_register(), Operand(lit)); 552 __ Mov(result_register(), Operand(lit));
553 codegen()->DoTest(this); 553 codegen()->DoTest(this);
554 } 554 }
555 } 555 }
556 556
557 557
558 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
559 Register reg) const {
560 DCHECK(count > 0);
561 __ Drop(count);
562 }
563
564
565 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
566 int count,
567 Register reg) const {
568 DCHECK(count > 0);
569 __ Drop(count);
570 __ Move(result_register(), reg);
571 }
572
573
574 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 558 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
575 Register reg) const { 559 Register reg) const {
576 DCHECK(count > 0); 560 DCHECK(count > 0);
577 if (count > 1) __ Drop(count - 1); 561 if (count > 1) codegen()->DropOperands(count - 1);
578 __ Poke(reg, 0); 562 __ Poke(reg, 0);
579 } 563 }
580 564
581 565
582 void FullCodeGenerator::TestContext::DropAndPlug(int count,
583 Register reg) const {
584 DCHECK(count > 0);
585 // For simplicity we always test the accumulator register.
586 __ Drop(count);
587 __ Mov(result_register(), reg);
588 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
589 codegen()->DoTest(this);
590 }
591
592
593 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 566 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
594 Label* materialize_false) const { 567 Label* materialize_false) const {
595 DCHECK(materialize_true == materialize_false); 568 DCHECK(materialize_true == materialize_false);
596 __ Bind(materialize_true); 569 __ Bind(materialize_true);
597 } 570 }
598 571
599 572
600 void FullCodeGenerator::AccumulatorValueContext::Plug( 573 void FullCodeGenerator::AccumulatorValueContext::Plug(
601 Label* materialize_true, 574 Label* materialize_true,
602 Label* materialize_false) const { 575 Label* materialize_false) const {
(...skipping 10 matching lines...) Expand all
613 void FullCodeGenerator::StackValueContext::Plug( 586 void FullCodeGenerator::StackValueContext::Plug(
614 Label* materialize_true, 587 Label* materialize_true,
615 Label* materialize_false) const { 588 Label* materialize_false) const {
616 Label done; 589 Label done;
617 __ Bind(materialize_true); 590 __ Bind(materialize_true);
618 __ LoadRoot(x10, Heap::kTrueValueRootIndex); 591 __ LoadRoot(x10, Heap::kTrueValueRootIndex);
619 __ B(&done); 592 __ B(&done);
620 __ Bind(materialize_false); 593 __ Bind(materialize_false);
621 __ LoadRoot(x10, Heap::kFalseValueRootIndex); 594 __ LoadRoot(x10, Heap::kFalseValueRootIndex);
622 __ Bind(&done); 595 __ Bind(&done);
623 __ Push(x10); 596 codegen()->PushOperand(x10);
624 } 597 }
625 598
626 599
627 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 600 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
628 Label* materialize_false) const { 601 Label* materialize_false) const {
629 DCHECK(materialize_true == true_label_); 602 DCHECK(materialize_true == true_label_);
630 DCHECK(materialize_false == false_label_); 603 DCHECK(materialize_false == false_label_);
631 } 604 }
632 605
633 606
634 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 607 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
635 Heap::RootListIndex value_root_index = 608 Heap::RootListIndex value_root_index =
636 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 609 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
637 __ LoadRoot(result_register(), value_root_index); 610 __ LoadRoot(result_register(), value_root_index);
638 } 611 }
639 612
640 613
641 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 614 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
642 Heap::RootListIndex value_root_index = 615 Heap::RootListIndex value_root_index =
643 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 616 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
644 __ LoadRoot(x10, value_root_index); 617 __ LoadRoot(x10, value_root_index);
645 __ Push(x10); 618 codegen()->PushOperand(x10);
646 } 619 }
647 620
648 621
649 void FullCodeGenerator::TestContext::Plug(bool flag) const { 622 void FullCodeGenerator::TestContext::Plug(bool flag) const {
650 codegen()->PrepareForBailoutBeforeSplit(condition(), 623 codegen()->PrepareForBailoutBeforeSplit(condition(),
651 true, 624 true,
652 true_label_, 625 true_label_,
653 false_label_); 626 false_label_);
654 if (flag) { 627 if (flag) {
655 if (true_label_ != fall_through_) { 628 if (true_label_ != fall_through_) {
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 kDontSaveFPRegs, 858 kDontSaveFPRegs,
886 EMIT_REMEMBERED_SET, 859 EMIT_REMEMBERED_SET,
887 OMIT_SMI_CHECK); 860 OMIT_SMI_CHECK);
888 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 861 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
889 break; 862 break;
890 } 863 }
891 864
892 case VariableLocation::LOOKUP: { 865 case VariableLocation::LOOKUP: {
893 Comment cmnt(masm_, "[ Function Declaration"); 866 Comment cmnt(masm_, "[ Function Declaration");
894 __ Mov(x2, Operand(variable->name())); 867 __ Mov(x2, Operand(variable->name()));
895 __ Push(x2); 868 PushOperand(x2);
896 // Push initial value for function declaration. 869 // Push initial value for function declaration.
897 VisitForStackValue(declaration->fun()); 870 VisitForStackValue(declaration->fun());
898 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 871 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
899 __ CallRuntime(Runtime::kDeclareLookupSlot); 872 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
900 break; 873 break;
901 } 874 }
902 } 875 }
903 } 876 }
904 877
905 878
906 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 879 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
907 // Call the runtime to declare the globals. 880 // Call the runtime to declare the globals.
908 __ Mov(x11, Operand(pairs)); 881 __ Mov(x11, Operand(pairs));
909 Register flags = xzr; 882 Register flags = xzr;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 __ Bind(&skip); 960 __ Bind(&skip);
988 961
989 __ Cbnz(x0, &next_test); 962 __ Cbnz(x0, &next_test);
990 __ Drop(1); // Switch value is no longer needed. 963 __ Drop(1); // Switch value is no longer needed.
991 __ B(clause->body_target()); 964 __ B(clause->body_target());
992 } 965 }
993 966
994 // Discard the test value and jump to the default if present, otherwise to 967 // Discard the test value and jump to the default if present, otherwise to
995 // the end of the statement. 968 // the end of the statement.
996 __ Bind(&next_test); 969 __ Bind(&next_test);
997 __ Drop(1); // Switch value is no longer needed. 970 DropOperands(1); // Switch value is no longer needed.
998 if (default_clause == NULL) { 971 if (default_clause == NULL) {
999 __ B(nested_statement.break_label()); 972 __ B(nested_statement.break_label());
1000 } else { 973 } else {
1001 __ B(default_clause->body_target()); 974 __ B(default_clause->body_target());
1002 } 975 }
1003 976
1004 // Compile all the case bodies. 977 // Compile all the case bodies.
1005 for (int i = 0; i < clauses->length(); i++) { 978 for (int i = 0; i < clauses->length(); i++) {
1006 Comment cmnt(masm_, "[ Case body"); 979 Comment cmnt(masm_, "[ Case body");
1007 CaseClause* clause = clauses->at(i); 980 CaseClause* clause = clauses->at(i);
(...skipping 16 matching lines...) Expand all
1024 997
1025 // TODO(all): This visitor probably needs better comments and a revisit. 998 // TODO(all): This visitor probably needs better comments and a revisit.
1026 999
1027 Label loop, exit; 1000 Label loop, exit;
1028 ForIn loop_statement(this, stmt); 1001 ForIn loop_statement(this, stmt);
1029 increment_loop_depth(); 1002 increment_loop_depth();
1030 1003
1031 // Get the object to enumerate over. 1004 // Get the object to enumerate over.
1032 SetExpressionAsStatementPosition(stmt->enumerable()); 1005 SetExpressionAsStatementPosition(stmt->enumerable());
1033 VisitForAccumulatorValue(stmt->enumerable()); 1006 VisitForAccumulatorValue(stmt->enumerable());
1007 OperandStackDepthIncrement(ForIn::kElementCount);
1034 1008
1035 // If the object is null or undefined, skip over the loop, otherwise convert 1009 // If the object is null or undefined, skip over the loop, otherwise convert
1036 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 1010 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
1037 Label convert, done_convert; 1011 Label convert, done_convert;
1038 __ JumpIfSmi(x0, &convert); 1012 __ JumpIfSmi(x0, &convert);
1039 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); 1013 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge);
1040 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); 1014 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit);
1041 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); 1015 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit);
1042 __ Bind(&convert); 1016 __ Bind(&convert);
1043 ToObjectStub stub(isolate()); 1017 ToObjectStub stub(isolate());
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 // TODO(all): We could use a callee saved register to avoid popping. 1149 // TODO(all): We could use a callee saved register to avoid popping.
1176 __ Pop(x0); 1150 __ Pop(x0);
1177 __ Add(x0, x0, Smi::FromInt(1)); 1151 __ Add(x0, x0, Smi::FromInt(1));
1178 __ Push(x0); 1152 __ Push(x0);
1179 1153
1180 EmitBackEdgeBookkeeping(stmt, &loop); 1154 EmitBackEdgeBookkeeping(stmt, &loop);
1181 __ B(&loop); 1155 __ B(&loop);
1182 1156
1183 // Remove the pointers stored on the stack. 1157 // Remove the pointers stored on the stack.
1184 __ Bind(loop_statement.break_label()); 1158 __ Bind(loop_statement.break_label());
1185 __ Drop(5); 1159 DropOperands(5);
1186 1160
1187 // Exit and decrement the loop depth. 1161 // Exit and decrement the loop depth.
1188 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1162 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1189 __ Bind(&exit); 1163 __ Bind(&exit);
1190 decrement_loop_depth(); 1164 decrement_loop_depth();
1191 } 1165 }
1192 1166
1193 1167
1194 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1168 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1195 bool pretenure) { 1169 bool pretenure) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 FastCloneRegExpStub stub(isolate()); 1418 FastCloneRegExpStub stub(isolate());
1445 __ CallStub(&stub); 1419 __ CallStub(&stub);
1446 context()->Plug(x0); 1420 context()->Plug(x0);
1447 } 1421 }
1448 1422
1449 1423
1450 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1424 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1451 Expression* expression = (property == NULL) ? NULL : property->value(); 1425 Expression* expression = (property == NULL) ? NULL : property->value();
1452 if (expression == NULL) { 1426 if (expression == NULL) {
1453 __ LoadRoot(x10, Heap::kNullValueRootIndex); 1427 __ LoadRoot(x10, Heap::kNullValueRootIndex);
1454 __ Push(x10); 1428 PushOperand(x10);
1455 } else { 1429 } else {
1456 VisitForStackValue(expression); 1430 VisitForStackValue(expression);
1457 if (NeedsHomeObject(expression)) { 1431 if (NeedsHomeObject(expression)) {
1458 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1432 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1459 property->kind() == ObjectLiteral::Property::SETTER); 1433 property->kind() == ObjectLiteral::Property::SETTER);
1460 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1434 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1461 EmitSetHomeObject(expression, offset, property->GetSlot()); 1435 EmitSetHomeObject(expression, offset, property->GetSlot());
1462 } 1436 }
1463 } 1437 }
1464 } 1438 }
(...skipping 24 matching lines...) Expand all
1489 AccessorTable accessor_table(zone()); 1463 AccessorTable accessor_table(zone());
1490 int property_index = 0; 1464 int property_index = 0;
1491 for (; property_index < expr->properties()->length(); property_index++) { 1465 for (; property_index < expr->properties()->length(); property_index++) {
1492 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1466 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1493 if (property->is_computed_name()) break; 1467 if (property->is_computed_name()) break;
1494 if (property->IsCompileTimeValue()) continue; 1468 if (property->IsCompileTimeValue()) continue;
1495 1469
1496 Literal* key = property->key()->AsLiteral(); 1470 Literal* key = property->key()->AsLiteral();
1497 Expression* value = property->value(); 1471 Expression* value = property->value();
1498 if (!result_saved) { 1472 if (!result_saved) {
1499 __ Push(x0); // Save result on stack 1473 PushOperand(x0); // Save result on stack
1500 result_saved = true; 1474 result_saved = true;
1501 } 1475 }
1502 switch (property->kind()) { 1476 switch (property->kind()) {
1503 case ObjectLiteral::Property::CONSTANT: 1477 case ObjectLiteral::Property::CONSTANT:
1504 UNREACHABLE(); 1478 UNREACHABLE();
1505 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1479 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1506 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1480 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1507 // Fall through. 1481 // Fall through.
1508 case ObjectLiteral::Property::COMPUTED: 1482 case ObjectLiteral::Property::COMPUTED:
1509 // It is safe to use [[Put]] here because the boilerplate already 1483 // It is safe to use [[Put]] here because the boilerplate already
(...skipping 10 matching lines...) Expand all
1520 1494
1521 if (NeedsHomeObject(value)) { 1495 if (NeedsHomeObject(value)) {
1522 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1496 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1523 } 1497 }
1524 } else { 1498 } else {
1525 VisitForEffect(value); 1499 VisitForEffect(value);
1526 } 1500 }
1527 break; 1501 break;
1528 } 1502 }
1529 __ Peek(x0, 0); 1503 __ Peek(x0, 0);
1530 __ Push(x0); 1504 PushOperand(x0);
1531 VisitForStackValue(key); 1505 VisitForStackValue(key);
1532 VisitForStackValue(value); 1506 VisitForStackValue(value);
1533 if (property->emit_store()) { 1507 if (property->emit_store()) {
1534 if (NeedsHomeObject(value)) { 1508 if (NeedsHomeObject(value)) {
1535 EmitSetHomeObject(value, 2, property->GetSlot()); 1509 EmitSetHomeObject(value, 2, property->GetSlot());
1536 } 1510 }
1537 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode 1511 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode
1538 __ Push(x0); 1512 PushOperand(x0);
1539 __ CallRuntime(Runtime::kSetProperty); 1513 CallRuntimeWithOperands(Runtime::kSetProperty);
1540 } else { 1514 } else {
1541 __ Drop(3); 1515 DropOperands(3);
1542 } 1516 }
1543 break; 1517 break;
1544 case ObjectLiteral::Property::PROTOTYPE: 1518 case ObjectLiteral::Property::PROTOTYPE:
1545 DCHECK(property->emit_store()); 1519 DCHECK(property->emit_store());
1546 // Duplicate receiver on stack. 1520 // Duplicate receiver on stack.
1547 __ Peek(x0, 0); 1521 __ Peek(x0, 0);
1548 __ Push(x0); 1522 PushOperand(x0);
1549 VisitForStackValue(value); 1523 VisitForStackValue(value);
1550 __ CallRuntime(Runtime::kInternalSetPrototype); 1524 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1551 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1525 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1552 NO_REGISTERS); 1526 NO_REGISTERS);
1553 break; 1527 break;
1554 case ObjectLiteral::Property::GETTER: 1528 case ObjectLiteral::Property::GETTER:
1555 if (property->emit_store()) { 1529 if (property->emit_store()) {
1556 accessor_table.lookup(key)->second->getter = property; 1530 accessor_table.lookup(key)->second->getter = property;
1557 } 1531 }
1558 break; 1532 break;
1559 case ObjectLiteral::Property::SETTER: 1533 case ObjectLiteral::Property::SETTER:
1560 if (property->emit_store()) { 1534 if (property->emit_store()) {
1561 accessor_table.lookup(key)->second->setter = property; 1535 accessor_table.lookup(key)->second->setter = property;
1562 } 1536 }
1563 break; 1537 break;
1564 } 1538 }
1565 } 1539 }
1566 1540
1567 // Emit code to define accessors, using only a single call to the runtime for 1541 // Emit code to define accessors, using only a single call to the runtime for
1568 // each pair of corresponding getters and setters. 1542 // each pair of corresponding getters and setters.
1569 for (AccessorTable::Iterator it = accessor_table.begin(); 1543 for (AccessorTable::Iterator it = accessor_table.begin();
1570 it != accessor_table.end(); 1544 it != accessor_table.end();
1571 ++it) { 1545 ++it) {
1572 __ Peek(x10, 0); // Duplicate receiver. 1546 __ Peek(x10, 0); // Duplicate receiver.
1573 __ Push(x10); 1547 PushOperand(x10);
1574 VisitForStackValue(it->first); 1548 VisitForStackValue(it->first);
1575 EmitAccessor(it->second->getter); 1549 EmitAccessor(it->second->getter);
1576 EmitAccessor(it->second->setter); 1550 EmitAccessor(it->second->setter);
1577 __ Mov(x10, Smi::FromInt(NONE)); 1551 __ Mov(x10, Smi::FromInt(NONE));
1578 __ Push(x10); 1552 PushOperand(x10);
1579 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1553 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1580 } 1554 }
1581 1555
1582 // Object literals have two parts. The "static" part on the left contains no 1556 // Object literals have two parts. The "static" part on the left contains no
1583 // computed property names, and so we can compute its map ahead of time; see 1557 // computed property names, and so we can compute its map ahead of time; see
1584 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1558 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1585 // starts with the first computed property name, and continues with all 1559 // starts with the first computed property name, and continues with all
1586 // properties to its right. All the code from above initializes the static 1560 // properties to its right. All the code from above initializes the static
1587 // component of the object literal, and arranges for the map of the result to 1561 // component of the object literal, and arranges for the map of the result to
1588 // reflect the static order in which the keys appear. For the dynamic 1562 // reflect the static order in which the keys appear. For the dynamic
1589 // properties, we compile them into a series of "SetOwnProperty" runtime 1563 // properties, we compile them into a series of "SetOwnProperty" runtime
1590 // calls. This will preserve insertion order. 1564 // calls. This will preserve insertion order.
1591 for (; property_index < expr->properties()->length(); property_index++) { 1565 for (; property_index < expr->properties()->length(); property_index++) {
1592 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1566 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1593 1567
1594 Expression* value = property->value(); 1568 Expression* value = property->value();
1595 if (!result_saved) { 1569 if (!result_saved) {
1596 __ Push(x0); // Save result on stack 1570 PushOperand(x0); // Save result on stack
1597 result_saved = true; 1571 result_saved = true;
1598 } 1572 }
1599 1573
1600 __ Peek(x10, 0); // Duplicate receiver. 1574 __ Peek(x10, 0); // Duplicate receiver.
1601 __ Push(x10); 1575 PushOperand(x10);
1602 1576
1603 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1577 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1604 DCHECK(!property->is_computed_name()); 1578 DCHECK(!property->is_computed_name());
1605 VisitForStackValue(value); 1579 VisitForStackValue(value);
1606 DCHECK(property->emit_store()); 1580 DCHECK(property->emit_store());
1607 __ CallRuntime(Runtime::kInternalSetPrototype); 1581 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1608 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1582 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1609 NO_REGISTERS); 1583 NO_REGISTERS);
1610 } else { 1584 } else {
1611 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1585 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1612 VisitForStackValue(value); 1586 VisitForStackValue(value);
1613 if (NeedsHomeObject(value)) { 1587 if (NeedsHomeObject(value)) {
1614 EmitSetHomeObject(value, 2, property->GetSlot()); 1588 EmitSetHomeObject(value, 2, property->GetSlot());
1615 } 1589 }
1616 1590
1617 switch (property->kind()) { 1591 switch (property->kind()) {
1618 case ObjectLiteral::Property::CONSTANT: 1592 case ObjectLiteral::Property::CONSTANT:
1619 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1593 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1620 case ObjectLiteral::Property::COMPUTED: 1594 case ObjectLiteral::Property::COMPUTED:
1621 if (property->emit_store()) { 1595 if (property->emit_store()) {
1622 __ Push(Smi::FromInt(NONE)); 1596 PushOperand(Smi::FromInt(NONE));
1623 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1597 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1624 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1598 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1625 } else { 1599 } else {
1626 __ Drop(3); 1600 DropOperands(3);
1627 } 1601 }
1628 break; 1602 break;
1629 1603
1630 case ObjectLiteral::Property::PROTOTYPE: 1604 case ObjectLiteral::Property::PROTOTYPE:
1631 UNREACHABLE(); 1605 UNREACHABLE();
1632 break; 1606 break;
1633 1607
1634 case ObjectLiteral::Property::GETTER: 1608 case ObjectLiteral::Property::GETTER:
1635 __ Push(Smi::FromInt(NONE)); 1609 PushOperand(Smi::FromInt(NONE));
1636 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1610 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1637 break; 1611 break;
1638 1612
1639 case ObjectLiteral::Property::SETTER: 1613 case ObjectLiteral::Property::SETTER:
1640 __ Push(Smi::FromInt(NONE)); 1614 PushOperand(Smi::FromInt(NONE));
1641 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1615 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1642 break; 1616 break;
1643 } 1617 }
1644 } 1618 }
1645 } 1619 }
1646 1620
1647 if (expr->has_function()) { 1621 if (expr->has_function()) {
1648 DCHECK(result_saved); 1622 DCHECK(result_saved);
1649 __ Peek(x0, 0); 1623 __ Peek(x0, 0);
1650 __ Push(x0); 1624 __ Push(x0);
1651 __ CallRuntime(Runtime::kToFastProperties); 1625 __ CallRuntime(Runtime::kToFastProperties);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 int array_index = 0; 1669 int array_index = 0;
1696 for (; array_index < length; array_index++) { 1670 for (; array_index < length; array_index++) {
1697 Expression* subexpr = subexprs->at(array_index); 1671 Expression* subexpr = subexprs->at(array_index);
1698 DCHECK(!subexpr->IsSpread()); 1672 DCHECK(!subexpr->IsSpread());
1699 1673
1700 // If the subexpression is a literal or a simple materialized literal it 1674 // If the subexpression is a literal or a simple materialized literal it
1701 // is already set in the cloned array. 1675 // is already set in the cloned array.
1702 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1676 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1703 1677
1704 if (!result_saved) { 1678 if (!result_saved) {
1705 __ Push(x0); 1679 PushOperand(x0);
1706 result_saved = true; 1680 result_saved = true;
1707 } 1681 }
1708 VisitForAccumulatorValue(subexpr); 1682 VisitForAccumulatorValue(subexpr);
1709 1683
1710 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); 1684 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index));
1711 __ Peek(StoreDescriptor::ReceiverRegister(), 0); 1685 __ Peek(StoreDescriptor::ReceiverRegister(), 0);
1712 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1686 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1713 Handle<Code> ic = 1687 Handle<Code> ic =
1714 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1688 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1715 CallIC(ic); 1689 CallIC(ic);
1716 1690
1717 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1691 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1718 } 1692 }
1719 1693
1720 // In case the array literal contains spread expressions it has two parts. The 1694 // In case the array literal contains spread expressions it has two parts. The
1721 // first part is the "static" array which has a literal index is handled 1695 // first part is the "static" array which has a literal index is handled
1722 // above. The second part is the part after the first spread expression 1696 // above. The second part is the part after the first spread expression
1723 // (inclusive) and these elements gets appended to the array. Note that the 1697 // (inclusive) and these elements gets appended to the array. Note that the
1724 // number elements an iterable produces is unknown ahead of time. 1698 // number elements an iterable produces is unknown ahead of time.
1725 if (array_index < length && result_saved) { 1699 if (array_index < length && result_saved) {
1726 __ Pop(x0); 1700 PopOperand(x0);
1727 result_saved = false; 1701 result_saved = false;
1728 } 1702 }
1729 for (; array_index < length; array_index++) { 1703 for (; array_index < length; array_index++) {
1730 Expression* subexpr = subexprs->at(array_index); 1704 Expression* subexpr = subexprs->at(array_index);
1731 1705
1732 __ Push(x0); 1706 PushOperand(x0);
1733 DCHECK(!subexpr->IsSpread()); 1707 DCHECK(!subexpr->IsSpread());
1734 VisitForStackValue(subexpr); 1708 VisitForStackValue(subexpr);
1735 __ CallRuntime(Runtime::kAppendElement); 1709 CallRuntimeWithOperands(Runtime::kAppendElement);
1736 1710
1737 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1711 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1738 } 1712 }
1739 1713
1740 if (result_saved) { 1714 if (result_saved) {
1741 context()->PlugTOS(); 1715 context()->PlugTOS();
1742 } else { 1716 } else {
1743 context()->Plug(x0); 1717 context()->Plug(x0);
1744 } 1718 }
1745 } 1719 }
(...skipping 20 matching lines...) Expand all
1766 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 1740 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
1767 } else { 1741 } else {
1768 VisitForStackValue(property->obj()); 1742 VisitForStackValue(property->obj());
1769 } 1743 }
1770 break; 1744 break;
1771 case NAMED_SUPER_PROPERTY: 1745 case NAMED_SUPER_PROPERTY:
1772 VisitForStackValue( 1746 VisitForStackValue(
1773 property->obj()->AsSuperPropertyReference()->this_var()); 1747 property->obj()->AsSuperPropertyReference()->this_var());
1774 VisitForAccumulatorValue( 1748 VisitForAccumulatorValue(
1775 property->obj()->AsSuperPropertyReference()->home_object()); 1749 property->obj()->AsSuperPropertyReference()->home_object());
1776 __ Push(result_register()); 1750 PushOperand(result_register());
1777 if (expr->is_compound()) { 1751 if (expr->is_compound()) {
1778 const Register scratch = x10; 1752 const Register scratch = x10;
1779 __ Peek(scratch, kPointerSize); 1753 __ Peek(scratch, kPointerSize);
1780 __ Push(scratch, result_register()); 1754 PushOperands(scratch, result_register());
1781 } 1755 }
1782 break; 1756 break;
1783 case KEYED_SUPER_PROPERTY: 1757 case KEYED_SUPER_PROPERTY:
1784 VisitForStackValue( 1758 VisitForStackValue(
1785 property->obj()->AsSuperPropertyReference()->this_var()); 1759 property->obj()->AsSuperPropertyReference()->this_var());
1786 VisitForStackValue( 1760 VisitForStackValue(
1787 property->obj()->AsSuperPropertyReference()->home_object()); 1761 property->obj()->AsSuperPropertyReference()->home_object());
1788 VisitForAccumulatorValue(property->key()); 1762 VisitForAccumulatorValue(property->key());
1789 __ Push(result_register()); 1763 PushOperand(result_register());
1790 if (expr->is_compound()) { 1764 if (expr->is_compound()) {
1791 const Register scratch1 = x10; 1765 const Register scratch1 = x10;
1792 const Register scratch2 = x11; 1766 const Register scratch2 = x11;
1793 __ Peek(scratch1, 2 * kPointerSize); 1767 __ Peek(scratch1, 2 * kPointerSize);
1794 __ Peek(scratch2, kPointerSize); 1768 __ Peek(scratch2, kPointerSize);
1795 __ Push(scratch1, scratch2, result_register()); 1769 PushOperands(scratch1, scratch2, result_register());
1796 } 1770 }
1797 break; 1771 break;
1798 case KEYED_PROPERTY: 1772 case KEYED_PROPERTY:
1799 if (expr->is_compound()) { 1773 if (expr->is_compound()) {
1800 VisitForStackValue(property->obj()); 1774 VisitForStackValue(property->obj());
1801 VisitForStackValue(property->key()); 1775 VisitForStackValue(property->key());
1802 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); 1776 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
1803 __ Peek(LoadDescriptor::NameRegister(), 0); 1777 __ Peek(LoadDescriptor::NameRegister(), 0);
1804 } else { 1778 } else {
1805 VisitForStackValue(property->obj()); 1779 VisitForStackValue(property->obj());
(...skipping 24 matching lines...) Expand all
1830 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1804 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1831 break; 1805 break;
1832 case KEYED_PROPERTY: 1806 case KEYED_PROPERTY:
1833 EmitKeyedPropertyLoad(property); 1807 EmitKeyedPropertyLoad(property);
1834 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1808 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1835 break; 1809 break;
1836 } 1810 }
1837 } 1811 }
1838 1812
1839 Token::Value op = expr->binary_op(); 1813 Token::Value op = expr->binary_op();
1840 __ Push(x0); // Left operand goes on the stack. 1814 PushOperand(x0); // Left operand goes on the stack.
1841 VisitForAccumulatorValue(expr->value()); 1815 VisitForAccumulatorValue(expr->value());
1842 1816
1843 AccumulatorValueContext context(this); 1817 AccumulatorValueContext context(this);
1844 if (ShouldInlineSmiCase(op)) { 1818 if (ShouldInlineSmiCase(op)) {
1845 EmitInlineSmiBinaryOp(expr->binary_operation(), 1819 EmitInlineSmiBinaryOp(expr->binary_operation(),
1846 op, 1820 op,
1847 expr->target(), 1821 expr->target(),
1848 expr->value()); 1822 expr->value());
1849 } else { 1823 } else {
1850 EmitBinaryOp(expr->binary_operation(), op); 1824 EmitBinaryOp(expr->binary_operation(), op);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 Literal* key = prop->key()->AsLiteral(); 1863 Literal* key = prop->key()->AsLiteral();
1890 DCHECK(!prop->IsSuperAccess()); 1864 DCHECK(!prop->IsSuperAccess());
1891 1865
1892 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); 1866 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
1893 __ Mov(LoadDescriptor::SlotRegister(), 1867 __ Mov(LoadDescriptor::SlotRegister(),
1894 SmiFromSlot(prop->PropertyFeedbackSlot())); 1868 SmiFromSlot(prop->PropertyFeedbackSlot()));
1895 CallLoadIC(NOT_INSIDE_TYPEOF); 1869 CallLoadIC(NOT_INSIDE_TYPEOF);
1896 } 1870 }
1897 1871
1898 1872
1899 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
1900 // Stack: receiver, home_object.
1901 SetExpressionPosition(prop);
1902 Literal* key = prop->key()->AsLiteral();
1903 DCHECK(!key->value()->IsSmi());
1904 DCHECK(prop->IsSuperAccess());
1905
1906 __ Push(key->value());
1907 __ CallRuntime(Runtime::kLoadFromSuper);
1908 }
1909
1910
1911 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1912 SetExpressionPosition(prop);
1913 // Call keyed load IC. It has arguments key and receiver in x0 and x1.
1914 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
1915 __ Mov(LoadDescriptor::SlotRegister(),
1916 SmiFromSlot(prop->PropertyFeedbackSlot()));
1917 CallIC(ic);
1918 }
1919
1920
1921 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
1922 // Stack: receiver, home_object, key.
1923 SetExpressionPosition(prop);
1924 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
1925 }
1926
1927
1928 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1873 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1929 Token::Value op, 1874 Token::Value op,
1930 Expression* left_expr, 1875 Expression* left_expr,
1931 Expression* right_expr) { 1876 Expression* right_expr) {
1932 Label done, both_smis, stub_call; 1877 Label done, both_smis, stub_call;
1933 1878
1934 // Get the arguments. 1879 // Get the arguments.
1935 Register left = x1; 1880 Register left = x1;
1936 Register right = x0; 1881 Register right = x0;
1937 Register result = x0; 1882 Register result = x0;
1938 __ Pop(left); 1883 PopOperand(left);
1939 1884
1940 // Perform combined smi check on both operands. 1885 // Perform combined smi check on both operands.
1941 __ Orr(x10, left, right); 1886 __ Orr(x10, left, right);
1942 JumpPatchSite patch_site(masm_); 1887 JumpPatchSite patch_site(masm_);
1943 patch_site.EmitJumpIfSmi(x10, &both_smis); 1888 patch_site.EmitJumpIfSmi(x10, &both_smis);
1944 1889
1945 __ Bind(&stub_call); 1890 __ Bind(&stub_call);
1946 1891
1947 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 1892 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
1948 { 1893 {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 default: 1963 default:
2019 UNREACHABLE(); 1964 UNREACHABLE();
2020 } 1965 }
2021 1966
2022 __ Bind(&done); 1967 __ Bind(&done);
2023 context()->Plug(x0); 1968 context()->Plug(x0);
2024 } 1969 }
2025 1970
2026 1971
2027 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 1972 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2028 __ Pop(x1); 1973 PopOperand(x1);
2029 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 1974 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2030 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. 1975 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code.
2031 { 1976 {
2032 Assembler::BlockPoolsScope scope(masm_); 1977 Assembler::BlockPoolsScope scope(masm_);
2033 CallIC(code, expr->BinaryOperationFeedbackId()); 1978 CallIC(code, expr->BinaryOperationFeedbackId());
2034 patch_site.EmitPatchInfo(); 1979 patch_site.EmitPatchInfo();
2035 } 1980 }
2036 context()->Plug(x0); 1981 context()->Plug(x0);
2037 } 1982 }
2038 1983
2039 1984
2040 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { 1985 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
2041 for (int i = 0; i < lit->properties()->length(); i++) { 1986 for (int i = 0; i < lit->properties()->length(); i++) {
2042 ObjectLiteral::Property* property = lit->properties()->at(i); 1987 ObjectLiteral::Property* property = lit->properties()->at(i);
2043 Expression* value = property->value(); 1988 Expression* value = property->value();
2044 1989
2045 Register scratch = x1; 1990 Register scratch = x1;
2046 if (property->is_static()) { 1991 if (property->is_static()) {
2047 __ Peek(scratch, kPointerSize); // constructor 1992 __ Peek(scratch, kPointerSize); // constructor
2048 } else { 1993 } else {
2049 __ Peek(scratch, 0); // prototype 1994 __ Peek(scratch, 0); // prototype
2050 } 1995 }
2051 __ Push(scratch); 1996 PushOperand(scratch);
2052 EmitPropertyKey(property, lit->GetIdForProperty(i)); 1997 EmitPropertyKey(property, lit->GetIdForProperty(i));
2053 1998
2054 // The static prototype property is read only. We handle the non computed 1999 // The static prototype property is read only. We handle the non computed
2055 // property name case in the parser. Since this is the only case where we 2000 // property name case in the parser. Since this is the only case where we
2056 // need to check for an own read only property we special case this so we do 2001 // need to check for an own read only property we special case this so we do
2057 // not need to do this for every property. 2002 // not need to do this for every property.
2058 if (property->is_static() && property->is_computed_name()) { 2003 if (property->is_static() && property->is_computed_name()) {
2059 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2004 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2060 __ Push(x0); 2005 __ Push(x0);
2061 } 2006 }
2062 2007
2063 VisitForStackValue(value); 2008 VisitForStackValue(value);
2064 if (NeedsHomeObject(value)) { 2009 if (NeedsHomeObject(value)) {
2065 EmitSetHomeObject(value, 2, property->GetSlot()); 2010 EmitSetHomeObject(value, 2, property->GetSlot());
2066 } 2011 }
2067 2012
2068 switch (property->kind()) { 2013 switch (property->kind()) {
2069 case ObjectLiteral::Property::CONSTANT: 2014 case ObjectLiteral::Property::CONSTANT:
2070 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2015 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2071 case ObjectLiteral::Property::PROTOTYPE: 2016 case ObjectLiteral::Property::PROTOTYPE:
2072 UNREACHABLE(); 2017 UNREACHABLE();
2073 case ObjectLiteral::Property::COMPUTED: 2018 case ObjectLiteral::Property::COMPUTED:
2074 __ Push(Smi::FromInt(DONT_ENUM)); 2019 PushOperand(Smi::FromInt(DONT_ENUM));
2075 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2020 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2076 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2021 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2077 break; 2022 break;
2078 2023
2079 case ObjectLiteral::Property::GETTER: 2024 case ObjectLiteral::Property::GETTER:
2080 __ Push(Smi::FromInt(DONT_ENUM)); 2025 PushOperand(Smi::FromInt(DONT_ENUM));
2081 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2026 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2082 break; 2027 break;
2083 2028
2084 case ObjectLiteral::Property::SETTER: 2029 case ObjectLiteral::Property::SETTER:
2085 __ Push(Smi::FromInt(DONT_ENUM)); 2030 PushOperand(Smi::FromInt(DONT_ENUM));
2086 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2031 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2087 break; 2032 break;
2088 2033
2089 default: 2034 default:
2090 UNREACHABLE(); 2035 UNREACHABLE();
2091 } 2036 }
2092 } 2037 }
2093 } 2038 }
2094 2039
2095 2040
2096 void FullCodeGenerator::EmitAssignment(Expression* expr, 2041 void FullCodeGenerator::EmitAssignment(Expression* expr,
2097 FeedbackVectorSlot slot) { 2042 FeedbackVectorSlot slot) {
2098 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2043 DCHECK(expr->IsValidReferenceExpressionOrThis());
2099 2044
2100 Property* prop = expr->AsProperty(); 2045 Property* prop = expr->AsProperty();
2101 LhsKind assign_type = Property::GetAssignType(prop); 2046 LhsKind assign_type = Property::GetAssignType(prop);
2102 2047
2103 switch (assign_type) { 2048 switch (assign_type) {
2104 case VARIABLE: { 2049 case VARIABLE: {
2105 Variable* var = expr->AsVariableProxy()->var(); 2050 Variable* var = expr->AsVariableProxy()->var();
2106 EffectContext context(this); 2051 EffectContext context(this);
2107 EmitVariableAssignment(var, Token::ASSIGN, slot); 2052 EmitVariableAssignment(var, Token::ASSIGN, slot);
2108 break; 2053 break;
2109 } 2054 }
2110 case NAMED_PROPERTY: { 2055 case NAMED_PROPERTY: {
2111 __ Push(x0); // Preserve value. 2056 PushOperand(x0); // Preserve value.
2112 VisitForAccumulatorValue(prop->obj()); 2057 VisitForAccumulatorValue(prop->obj());
2113 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid 2058 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid
2114 // this copy. 2059 // this copy.
2115 __ Mov(StoreDescriptor::ReceiverRegister(), x0); 2060 __ Mov(StoreDescriptor::ReceiverRegister(), x0);
2116 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. 2061 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2117 __ Mov(StoreDescriptor::NameRegister(), 2062 __ Mov(StoreDescriptor::NameRegister(),
2118 Operand(prop->key()->AsLiteral()->value())); 2063 Operand(prop->key()->AsLiteral()->value()));
2119 EmitLoadStoreICSlot(slot); 2064 EmitLoadStoreICSlot(slot);
2120 CallStoreIC(); 2065 CallStoreIC();
2121 break; 2066 break;
2122 } 2067 }
2123 case NAMED_SUPER_PROPERTY: { 2068 case NAMED_SUPER_PROPERTY: {
2124 __ Push(x0); 2069 PushOperand(x0);
2125 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2070 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2126 VisitForAccumulatorValue( 2071 VisitForAccumulatorValue(
2127 prop->obj()->AsSuperPropertyReference()->home_object()); 2072 prop->obj()->AsSuperPropertyReference()->home_object());
2128 // stack: value, this; x0: home_object 2073 // stack: value, this; x0: home_object
2129 Register scratch = x10; 2074 Register scratch = x10;
2130 Register scratch2 = x11; 2075 Register scratch2 = x11;
2131 __ mov(scratch, result_register()); // home_object 2076 __ mov(scratch, result_register()); // home_object
2132 __ Peek(x0, kPointerSize); // value 2077 __ Peek(x0, kPointerSize); // value
2133 __ Peek(scratch2, 0); // this 2078 __ Peek(scratch2, 0); // this
2134 __ Poke(scratch2, kPointerSize); // this 2079 __ Poke(scratch2, kPointerSize); // this
2135 __ Poke(scratch, 0); // home_object 2080 __ Poke(scratch, 0); // home_object
2136 // stack: this, home_object; x0: value 2081 // stack: this, home_object; x0: value
2137 EmitNamedSuperPropertyStore(prop); 2082 EmitNamedSuperPropertyStore(prop);
2138 break; 2083 break;
2139 } 2084 }
2140 case KEYED_SUPER_PROPERTY: { 2085 case KEYED_SUPER_PROPERTY: {
2141 __ Push(x0); 2086 PushOperand(x0);
2142 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2087 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2143 VisitForStackValue( 2088 VisitForStackValue(
2144 prop->obj()->AsSuperPropertyReference()->home_object()); 2089 prop->obj()->AsSuperPropertyReference()->home_object());
2145 VisitForAccumulatorValue(prop->key()); 2090 VisitForAccumulatorValue(prop->key());
2146 Register scratch = x10; 2091 Register scratch = x10;
2147 Register scratch2 = x11; 2092 Register scratch2 = x11;
2148 __ Peek(scratch2, 2 * kPointerSize); // value 2093 __ Peek(scratch2, 2 * kPointerSize); // value
2149 // stack: value, this, home_object; x0: key, x11: value 2094 // stack: value, this, home_object; x0: key, x11: value
2150 __ Peek(scratch, kPointerSize); // this 2095 __ Peek(scratch, kPointerSize); // this
2151 __ Poke(scratch, 2 * kPointerSize); 2096 __ Poke(scratch, 2 * kPointerSize);
2152 __ Peek(scratch, 0); // home_object 2097 __ Peek(scratch, 0); // home_object
2153 __ Poke(scratch, kPointerSize); 2098 __ Poke(scratch, kPointerSize);
2154 __ Poke(x0, 0); 2099 __ Poke(x0, 0);
2155 __ Move(x0, scratch2); 2100 __ Move(x0, scratch2);
2156 // stack: this, home_object, key; x0: value. 2101 // stack: this, home_object, key; x0: value.
2157 EmitKeyedSuperPropertyStore(prop); 2102 EmitKeyedSuperPropertyStore(prop);
2158 break; 2103 break;
2159 } 2104 }
2160 case KEYED_PROPERTY: { 2105 case KEYED_PROPERTY: {
2161 __ Push(x0); // Preserve value. 2106 PushOperand(x0); // Preserve value.
2162 VisitForStackValue(prop->obj()); 2107 VisitForStackValue(prop->obj());
2163 VisitForAccumulatorValue(prop->key()); 2108 VisitForAccumulatorValue(prop->key());
2164 __ Mov(StoreDescriptor::NameRegister(), x0); 2109 __ Mov(StoreDescriptor::NameRegister(), x0);
2165 __ Pop(StoreDescriptor::ReceiverRegister(), 2110 PopOperands(StoreDescriptor::ReceiverRegister(),
2166 StoreDescriptor::ValueRegister()); 2111 StoreDescriptor::ValueRegister());
2167 EmitLoadStoreICSlot(slot); 2112 EmitLoadStoreICSlot(slot);
2168 Handle<Code> ic = 2113 Handle<Code> ic =
2169 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2114 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2170 CallIC(ic); 2115 CallIC(ic);
2171 break; 2116 break;
2172 } 2117 }
2173 } 2118 }
2174 context()->Plug(x0); 2119 context()->Plug(x0);
2175 } 2120 }
2176 2121
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 2236
2292 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2237 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2293 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); 2238 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment");
2294 // Assignment to a property, using a named store IC. 2239 // Assignment to a property, using a named store IC.
2295 Property* prop = expr->target()->AsProperty(); 2240 Property* prop = expr->target()->AsProperty();
2296 DCHECK(prop != NULL); 2241 DCHECK(prop != NULL);
2297 DCHECK(prop->key()->IsLiteral()); 2242 DCHECK(prop->key()->IsLiteral());
2298 2243
2299 __ Mov(StoreDescriptor::NameRegister(), 2244 __ Mov(StoreDescriptor::NameRegister(),
2300 Operand(prop->key()->AsLiteral()->value())); 2245 Operand(prop->key()->AsLiteral()->value()));
2301 __ Pop(StoreDescriptor::ReceiverRegister()); 2246 PopOperand(StoreDescriptor::ReceiverRegister());
2302 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2247 EmitLoadStoreICSlot(expr->AssignmentSlot());
2303 CallStoreIC(); 2248 CallStoreIC();
2304 2249
2305 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2250 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2306 context()->Plug(x0); 2251 context()->Plug(x0);
2307 } 2252 }
2308 2253
2309 2254
2310 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2255 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2311 // Assignment to named property of super. 2256 // Assignment to named property of super.
2312 // x0 : value 2257 // x0 : value
2313 // stack : receiver ('this'), home_object 2258 // stack : receiver ('this'), home_object
2314 DCHECK(prop != NULL); 2259 DCHECK(prop != NULL);
2315 Literal* key = prop->key()->AsLiteral(); 2260 Literal* key = prop->key()->AsLiteral();
2316 DCHECK(key != NULL); 2261 DCHECK(key != NULL);
2317 2262
2318 __ Push(key->value()); 2263 PushOperand(key->value());
2319 __ Push(x0); 2264 PushOperand(x0);
2320 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2265 CallRuntimeWithOperands(is_strict(language_mode())
2321 : Runtime::kStoreToSuper_Sloppy)); 2266 ? Runtime::kStoreToSuper_Strict
2267 : Runtime::kStoreToSuper_Sloppy);
2322 } 2268 }
2323 2269
2324 2270
2325 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2271 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2326 // Assignment to named property of super. 2272 // Assignment to named property of super.
2327 // x0 : value 2273 // x0 : value
2328 // stack : receiver ('this'), home_object, key 2274 // stack : receiver ('this'), home_object, key
2329 DCHECK(prop != NULL); 2275 DCHECK(prop != NULL);
2330 2276
2331 __ Push(x0); 2277 PushOperand(x0);
2332 __ CallRuntime((is_strict(language_mode()) 2278 CallRuntimeWithOperands(is_strict(language_mode())
2333 ? Runtime::kStoreKeyedToSuper_Strict 2279 ? Runtime::kStoreKeyedToSuper_Strict
2334 : Runtime::kStoreKeyedToSuper_Sloppy)); 2280 : Runtime::kStoreKeyedToSuper_Sloppy);
2335 } 2281 }
2336 2282
2337 2283
2338 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2284 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2339 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); 2285 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment");
2340 // Assignment to a property, using a keyed store IC. 2286 // Assignment to a property, using a keyed store IC.
2341 2287
2342 // TODO(all): Could we pass this in registers rather than on the stack? 2288 // TODO(all): Could we pass this in registers rather than on the stack?
2343 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); 2289 PopOperands(StoreDescriptor::NameRegister(),
2290 StoreDescriptor::ReceiverRegister());
2344 DCHECK(StoreDescriptor::ValueRegister().is(x0)); 2291 DCHECK(StoreDescriptor::ValueRegister().is(x0));
2345 2292
2346 Handle<Code> ic = 2293 Handle<Code> ic =
2347 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2294 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2348 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2295 EmitLoadStoreICSlot(expr->AssignmentSlot());
2349 CallIC(ic); 2296 CallIC(ic);
2350 2297
2351 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2298 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2352 context()->Plug(x0); 2299 context()->Plug(x0);
2353 } 2300 }
(...skipping 13 matching lines...) Expand all
2367 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2314 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2368 VisitForStackValue( 2315 VisitForStackValue(
2369 expr->obj()->AsSuperPropertyReference()->home_object()); 2316 expr->obj()->AsSuperPropertyReference()->home_object());
2370 EmitNamedSuperPropertyLoad(expr); 2317 EmitNamedSuperPropertyLoad(expr);
2371 } 2318 }
2372 } else { 2319 } else {
2373 if (!expr->IsSuperAccess()) { 2320 if (!expr->IsSuperAccess()) {
2374 VisitForStackValue(expr->obj()); 2321 VisitForStackValue(expr->obj());
2375 VisitForAccumulatorValue(expr->key()); 2322 VisitForAccumulatorValue(expr->key());
2376 __ Move(LoadDescriptor::NameRegister(), x0); 2323 __ Move(LoadDescriptor::NameRegister(), x0);
2377 __ Pop(LoadDescriptor::ReceiverRegister()); 2324 PopOperand(LoadDescriptor::ReceiverRegister());
2378 EmitKeyedPropertyLoad(expr); 2325 EmitKeyedPropertyLoad(expr);
2379 } else { 2326 } else {
2380 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2327 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2381 VisitForStackValue( 2328 VisitForStackValue(
2382 expr->obj()->AsSuperPropertyReference()->home_object()); 2329 expr->obj()->AsSuperPropertyReference()->home_object());
2383 VisitForStackValue(expr->key()); 2330 VisitForStackValue(expr->key());
2384 EmitKeyedSuperPropertyLoad(expr); 2331 EmitKeyedSuperPropertyLoad(expr);
2385 } 2332 }
2386 } 2333 }
2387 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2334 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
(...skipping 21 matching lines...) Expand all
2409 { StackValueContext context(this); 2356 { StackValueContext context(this);
2410 EmitVariableLoad(callee->AsVariableProxy()); 2357 EmitVariableLoad(callee->AsVariableProxy());
2411 PrepareForBailout(callee, NO_REGISTERS); 2358 PrepareForBailout(callee, NO_REGISTERS);
2412 } 2359 }
2413 // Push undefined as receiver. This is patched in the method prologue if it 2360 // Push undefined as receiver. This is patched in the method prologue if it
2414 // is a sloppy mode method. 2361 // is a sloppy mode method.
2415 { 2362 {
2416 UseScratchRegisterScope temps(masm_); 2363 UseScratchRegisterScope temps(masm_);
2417 Register temp = temps.AcquireX(); 2364 Register temp = temps.AcquireX();
2418 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); 2365 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex);
2419 __ Push(temp); 2366 PushOperand(temp);
2420 } 2367 }
2421 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2368 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2422 } else { 2369 } else {
2423 // Load the function from the receiver. 2370 // Load the function from the receiver.
2424 DCHECK(callee->IsProperty()); 2371 DCHECK(callee->IsProperty());
2425 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2372 DCHECK(!callee->AsProperty()->IsSuperAccess());
2426 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 2373 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
2427 EmitNamedPropertyLoad(callee->AsProperty()); 2374 EmitNamedPropertyLoad(callee->AsProperty());
2428 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2375 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2429 // Push the target function under the receiver. 2376 // Push the target function under the receiver.
2430 __ Pop(x10); 2377 PopOperand(x10);
2431 __ Push(x0, x10); 2378 PushOperands(x0, x10);
2432 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2379 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2433 } 2380 }
2434 2381
2435 EmitCall(expr, convert_mode); 2382 EmitCall(expr, convert_mode);
2436 } 2383 }
2437 2384
2438 2385
2439 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2386 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2440 ASM_LOCATION("FullCodeGenerator::EmitSuperCallWithLoadIC"); 2387 ASM_LOCATION("FullCodeGenerator::EmitSuperCallWithLoadIC");
2441 Expression* callee = expr->expression(); 2388 Expression* callee = expr->expression();
2442 DCHECK(callee->IsProperty()); 2389 DCHECK(callee->IsProperty());
2443 Property* prop = callee->AsProperty(); 2390 Property* prop = callee->AsProperty();
2444 DCHECK(prop->IsSuperAccess()); 2391 DCHECK(prop->IsSuperAccess());
2445 SetExpressionPosition(prop); 2392 SetExpressionPosition(prop);
2446 2393
2447 Literal* key = prop->key()->AsLiteral(); 2394 Literal* key = prop->key()->AsLiteral();
2448 DCHECK(!key->value()->IsSmi()); 2395 DCHECK(!key->value()->IsSmi());
2449 2396
2450 // Load the function from the receiver. 2397 // Load the function from the receiver.
2451 const Register scratch = x10; 2398 const Register scratch = x10;
2452 SuperPropertyReference* super_ref = 2399 SuperPropertyReference* super_ref =
2453 callee->AsProperty()->obj()->AsSuperPropertyReference(); 2400 callee->AsProperty()->obj()->AsSuperPropertyReference();
2454 VisitForStackValue(super_ref->home_object()); 2401 VisitForStackValue(super_ref->home_object());
2455 VisitForAccumulatorValue(super_ref->this_var()); 2402 VisitForAccumulatorValue(super_ref->this_var());
2456 __ Push(x0); 2403 PushOperand(x0);
2457 __ Peek(scratch, kPointerSize); 2404 __ Peek(scratch, kPointerSize);
2458 __ Push(x0, scratch); 2405 PushOperands(x0, scratch);
2459 __ Push(key->value()); 2406 PushOperand(key->value());
2460 2407
2461 // Stack here: 2408 // Stack here:
2462 // - home_object 2409 // - home_object
2463 // - this (receiver) 2410 // - this (receiver)
2464 // - this (receiver) <-- LoadFromSuper will pop here and below. 2411 // - this (receiver) <-- LoadFromSuper will pop here and below.
2465 // - home_object 2412 // - home_object
2466 __ CallRuntime(Runtime::kLoadFromSuper); 2413 // - key
2414 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2467 2415
2468 // Replace home_object with target function. 2416 // Replace home_object with target function.
2469 __ Poke(x0, kPointerSize); 2417 __ Poke(x0, kPointerSize);
2470 2418
2471 // Stack here: 2419 // Stack here:
2472 // - target function 2420 // - target function
2473 // - this (receiver) 2421 // - this (receiver)
2474 EmitCall(expr); 2422 EmitCall(expr);
2475 } 2423 }
2476 2424
2477 2425
2478 // Code common for calls using the IC. 2426 // Code common for calls using the IC.
2479 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2427 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2480 Expression* key) { 2428 Expression* key) {
2481 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); 2429 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC");
2482 // Load the key. 2430 // Load the key.
2483 VisitForAccumulatorValue(key); 2431 VisitForAccumulatorValue(key);
2484 2432
2485 Expression* callee = expr->expression(); 2433 Expression* callee = expr->expression();
2486 2434
2487 // Load the function from the receiver. 2435 // Load the function from the receiver.
2488 DCHECK(callee->IsProperty()); 2436 DCHECK(callee->IsProperty());
2489 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 2437 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
2490 __ Move(LoadDescriptor::NameRegister(), x0); 2438 __ Move(LoadDescriptor::NameRegister(), x0);
2491 EmitKeyedPropertyLoad(callee->AsProperty()); 2439 EmitKeyedPropertyLoad(callee->AsProperty());
2492 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2440 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2493 2441
2494 // Push the target function under the receiver. 2442 // Push the target function under the receiver.
2495 __ Pop(x10); 2443 PopOperand(x10);
2496 __ Push(x0, x10); 2444 PushOperands(x0, x10);
2497 2445
2498 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2446 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2499 } 2447 }
2500 2448
2501 2449
2502 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2450 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2503 ASM_LOCATION("FullCodeGenerator::EmitKeyedSuperCallWithLoadIC"); 2451 ASM_LOCATION("FullCodeGenerator::EmitKeyedSuperCallWithLoadIC");
2504 Expression* callee = expr->expression(); 2452 Expression* callee = expr->expression();
2505 DCHECK(callee->IsProperty()); 2453 DCHECK(callee->IsProperty());
2506 Property* prop = callee->AsProperty(); 2454 Property* prop = callee->AsProperty();
2507 DCHECK(prop->IsSuperAccess()); 2455 DCHECK(prop->IsSuperAccess());
2508 SetExpressionPosition(prop); 2456 SetExpressionPosition(prop);
2509 2457
2510 // Load the function from the receiver. 2458 // Load the function from the receiver.
2511 const Register scratch = x10; 2459 const Register scratch = x10;
2512 SuperPropertyReference* super_ref = 2460 SuperPropertyReference* super_ref =
2513 callee->AsProperty()->obj()->AsSuperPropertyReference(); 2461 callee->AsProperty()->obj()->AsSuperPropertyReference();
2514 VisitForStackValue(super_ref->home_object()); 2462 VisitForStackValue(super_ref->home_object());
2515 VisitForAccumulatorValue(super_ref->this_var()); 2463 VisitForAccumulatorValue(super_ref->this_var());
2516 __ Push(x0); 2464 PushOperand(x0);
2517 __ Peek(scratch, kPointerSize); 2465 __ Peek(scratch, kPointerSize);
2518 __ Push(x0, scratch); 2466 PushOperands(x0, scratch);
2519 VisitForStackValue(prop->key()); 2467 VisitForStackValue(prop->key());
2520 2468
2521 // Stack here: 2469 // Stack here:
2522 // - home_object 2470 // - home_object
2523 // - this (receiver) 2471 // - this (receiver)
2524 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2472 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2525 // - home_object 2473 // - home_object
2526 // - key 2474 // - key
2527 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2475 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2528 2476
2529 // Replace home_object with target function. 2477 // Replace home_object with target function.
2530 __ Poke(x0, kPointerSize); 2478 __ Poke(x0, kPointerSize);
2531 2479
2532 // Stack here: 2480 // Stack here:
2533 // - target function 2481 // - target function
2534 // - this (receiver) 2482 // - this (receiver)
2535 EmitCall(expr); 2483 EmitCall(expr);
2536 } 2484 }
2537 2485
(...skipping 18 matching lines...) Expand all
2556 EmitProfilingCounterHandlingForReturnSequence(true); 2504 EmitProfilingCounterHandlingForReturnSequence(true);
2557 } 2505 }
2558 Handle<Code> ic = 2506 Handle<Code> ic =
2559 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2507 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2560 .code(); 2508 .code();
2561 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); 2509 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot()));
2562 __ Peek(x1, (arg_count + 1) * kXRegSize); 2510 __ Peek(x1, (arg_count + 1) * kXRegSize);
2563 // Don't assign a type feedback id to the IC, since type feedback is provided 2511 // Don't assign a type feedback id to the IC, since type feedback is provided
2564 // by the vector above. 2512 // by the vector above.
2565 CallIC(ic); 2513 CallIC(ic);
2514 OperandStackDepthDecrement(arg_count + 1);
2566 2515
2567 RecordJSReturnSite(expr); 2516 RecordJSReturnSite(expr);
2568 // Restore context register. 2517 // Restore context register.
2569 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2518 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2570 context()->DropAndPlug(1, x0); 2519 context()->DropAndPlug(1, x0);
2571 } 2520 }
2572 2521
2573 2522
2574 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2523 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2575 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); 2524 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval");
(...skipping 28 matching lines...) Expand all
2604 SetExpressionPosition(callee); 2553 SetExpressionPosition(callee);
2605 // Generate code for loading from variables potentially shadowed 2554 // Generate code for loading from variables potentially shadowed
2606 // by eval-introduced variables. 2555 // by eval-introduced variables.
2607 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2556 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2608 2557
2609 __ Bind(&slow); 2558 __ Bind(&slow);
2610 // Call the runtime to find the function to call (returned in x0) 2559 // Call the runtime to find the function to call (returned in x0)
2611 // and the object holding it (returned in x1). 2560 // and the object holding it (returned in x1).
2612 __ Push(callee->name()); 2561 __ Push(callee->name());
2613 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2562 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2614 __ Push(x0, x1); // Receiver, function. 2563 PushOperands(x0, x1); // Receiver, function.
2615 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2564 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2616 2565
2617 // If fast case code has been generated, emit code to push the 2566 // If fast case code has been generated, emit code to push the
2618 // function and receiver and have the slow path jump around this 2567 // function and receiver and have the slow path jump around this
2619 // code. 2568 // code.
2620 if (done.is_linked()) { 2569 if (done.is_linked()) {
2621 Label call; 2570 Label call;
2622 __ B(&call); 2571 __ B(&call);
2623 __ Bind(&done); 2572 __ Bind(&done);
2624 // Push function. 2573 // Push function.
2625 // The receiver is implicitly the global receiver. Indicate this 2574 // The receiver is implicitly the global receiver. Indicate this
2626 // by passing the undefined to the call function stub. 2575 // by passing the undefined to the call function stub.
2627 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); 2576 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
2628 __ Push(x0, x1); 2577 __ Push(x0, x1);
2629 __ Bind(&call); 2578 __ Bind(&call);
2630 } 2579 }
2631 } else { 2580 } else {
2632 VisitForStackValue(callee); 2581 VisitForStackValue(callee);
2633 // refEnv.WithBaseObject() 2582 // refEnv.WithBaseObject()
2634 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); 2583 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
2635 __ Push(x10); // Reserved receiver slot. 2584 PushOperand(x10); // Reserved receiver slot.
2636 } 2585 }
2637 } 2586 }
2638 2587
2639 2588
2640 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2589 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2641 ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall"); 2590 ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall");
2642 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2591 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2643 // to resolve the function we need to call. Then we call the resolved 2592 // to resolve the function we need to call. Then we call the resolved
2644 // function using the given arguments. 2593 // function using the given arguments.
2645 ZoneList<Expression*>* args = expr->arguments(); 2594 ZoneList<Expression*>* args = expr->arguments();
(...skipping 19 matching lines...) Expand all
2665 2614
2666 // Record source position for debugger. 2615 // Record source position for debugger.
2667 SetCallPosition(expr); 2616 SetCallPosition(expr);
2668 2617
2669 // Call the evaluated function. 2618 // Call the evaluated function.
2670 __ Peek(x1, (arg_count + 1) * kXRegSize); 2619 __ Peek(x1, (arg_count + 1) * kXRegSize);
2671 __ Mov(x0, arg_count); 2620 __ Mov(x0, arg_count);
2672 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2621 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2673 expr->tail_call_mode()), 2622 expr->tail_call_mode()),
2674 RelocInfo::CODE_TARGET); 2623 RelocInfo::CODE_TARGET);
2624 OperandStackDepthDecrement(arg_count + 1);
2675 RecordJSReturnSite(expr); 2625 RecordJSReturnSite(expr);
2676 // Restore context register. 2626 // Restore context register.
2677 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2627 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2678 context()->DropAndPlug(1, x0); 2628 context()->DropAndPlug(1, x0);
2679 } 2629 }
2680 2630
2681 2631
2682 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2632 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2683 Comment cmnt(masm_, "[ CallNew"); 2633 Comment cmnt(masm_, "[ CallNew");
2684 // According to ECMA-262, section 11.2.2, page 44, the function 2634 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2705 // Load function and argument count into x1 and x0. 2655 // Load function and argument count into x1 and x0.
2706 __ Mov(x0, arg_count); 2656 __ Mov(x0, arg_count);
2707 __ Peek(x1, arg_count * kXRegSize); 2657 __ Peek(x1, arg_count * kXRegSize);
2708 2658
2709 // Record call targets in unoptimized code. 2659 // Record call targets in unoptimized code.
2710 __ EmitLoadTypeFeedbackVector(x2); 2660 __ EmitLoadTypeFeedbackVector(x2);
2711 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); 2661 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot()));
2712 2662
2713 CallConstructStub stub(isolate()); 2663 CallConstructStub stub(isolate());
2714 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2664 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2665 OperandStackDepthDecrement(arg_count + 1);
2715 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2666 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2716 // Restore context register. 2667 // Restore context register.
2717 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2668 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2718 context()->Plug(x0); 2669 context()->Plug(x0);
2719 } 2670 }
2720 2671
2721 2672
2722 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2673 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2723 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); 2674 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall");
2724 SuperCallReference* super_call_ref = 2675 SuperCallReference* super_call_ref =
2725 expr->expression()->AsSuperCallReference(); 2676 expr->expression()->AsSuperCallReference();
2726 DCHECK_NOT_NULL(super_call_ref); 2677 DCHECK_NOT_NULL(super_call_ref);
2727 2678
2728 // Push the super constructor target on the stack (may be null, 2679 // Push the super constructor target on the stack (may be null,
2729 // but the Construct builtin can deal with that properly). 2680 // but the Construct builtin can deal with that properly).
2730 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2681 VisitForAccumulatorValue(super_call_ref->this_function_var());
2731 __ AssertFunction(result_register()); 2682 __ AssertFunction(result_register());
2732 __ Ldr(result_register(), 2683 __ Ldr(result_register(),
2733 FieldMemOperand(result_register(), HeapObject::kMapOffset)); 2684 FieldMemOperand(result_register(), HeapObject::kMapOffset));
2734 __ Ldr(result_register(), 2685 __ Ldr(result_register(),
2735 FieldMemOperand(result_register(), Map::kPrototypeOffset)); 2686 FieldMemOperand(result_register(), Map::kPrototypeOffset));
2736 __ Push(result_register()); 2687 PushOperand(result_register());
2737 2688
2738 // Push the arguments ("left-to-right") on the stack. 2689 // Push the arguments ("left-to-right") on the stack.
2739 ZoneList<Expression*>* args = expr->arguments(); 2690 ZoneList<Expression*>* args = expr->arguments();
2740 int arg_count = args->length(); 2691 int arg_count = args->length();
2741 for (int i = 0; i < arg_count; i++) { 2692 for (int i = 0; i < arg_count; i++) {
2742 VisitForStackValue(args->at(i)); 2693 VisitForStackValue(args->at(i));
2743 } 2694 }
2744 2695
2745 // Call the construct call builtin that handles allocation and 2696 // Call the construct call builtin that handles allocation and
2746 // constructor invocation. 2697 // constructor invocation.
2747 SetConstructCallPosition(expr); 2698 SetConstructCallPosition(expr);
2748 2699
2749 // Load new target into x3. 2700 // Load new target into x3.
2750 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2701 VisitForAccumulatorValue(super_call_ref->new_target_var());
2751 __ Mov(x3, result_register()); 2702 __ Mov(x3, result_register());
2752 2703
2753 // Load function and argument count into x1 and x0. 2704 // Load function and argument count into x1 and x0.
2754 __ Mov(x0, arg_count); 2705 __ Mov(x0, arg_count);
2755 __ Peek(x1, arg_count * kXRegSize); 2706 __ Peek(x1, arg_count * kXRegSize);
2756 2707
2757 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2708 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2709 OperandStackDepthDecrement(arg_count + 1);
2758 2710
2759 RecordJSReturnSite(expr); 2711 RecordJSReturnSite(expr);
2760 2712
2761 // Restore context register. 2713 // Restore context register.
2762 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2714 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2763 context()->Plug(x0); 2715 context()->Plug(x0);
2764 } 2716 }
2765 2717
2766 2718
2767 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2719 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
2971 DCHECK_EQ(3, args->length()); 2923 DCHECK_EQ(3, args->length());
2972 2924
2973 Register string = x0; 2925 Register string = x0;
2974 Register index = x1; 2926 Register index = x1;
2975 Register value = x2; 2927 Register value = x2;
2976 Register scratch = x10; 2928 Register scratch = x10;
2977 2929
2978 VisitForStackValue(args->at(0)); // index 2930 VisitForStackValue(args->at(0)); // index
2979 VisitForStackValue(args->at(1)); // value 2931 VisitForStackValue(args->at(1)); // value
2980 VisitForAccumulatorValue(args->at(2)); // string 2932 VisitForAccumulatorValue(args->at(2)); // string
2981 __ Pop(value, index); 2933 PopOperands(value, index);
2982 2934
2983 if (FLAG_debug_code) { 2935 if (FLAG_debug_code) {
2984 __ AssertSmi(value, kNonSmiValue); 2936 __ AssertSmi(value, kNonSmiValue);
2985 __ AssertSmi(index, kNonSmiIndex); 2937 __ AssertSmi(index, kNonSmiIndex);
2986 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 2938 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
2987 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, 2939 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch,
2988 one_byte_seq_type); 2940 one_byte_seq_type);
2989 } 2941 }
2990 2942
2991 __ Add(scratch, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); 2943 __ Add(scratch, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
2992 __ SmiUntag(value); 2944 __ SmiUntag(value);
2993 __ SmiUntag(index); 2945 __ SmiUntag(index);
2994 __ Strb(value, MemOperand(scratch, index)); 2946 __ Strb(value, MemOperand(scratch, index));
2995 context()->Plug(string); 2947 context()->Plug(string);
2996 } 2948 }
2997 2949
2998 2950
2999 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { 2951 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
3000 ZoneList<Expression*>* args = expr->arguments(); 2952 ZoneList<Expression*>* args = expr->arguments();
3001 DCHECK_EQ(3, args->length()); 2953 DCHECK_EQ(3, args->length());
3002 2954
3003 Register string = x0; 2955 Register string = x0;
3004 Register index = x1; 2956 Register index = x1;
3005 Register value = x2; 2957 Register value = x2;
3006 Register scratch = x10; 2958 Register scratch = x10;
3007 2959
3008 VisitForStackValue(args->at(0)); // index 2960 VisitForStackValue(args->at(0)); // index
3009 VisitForStackValue(args->at(1)); // value 2961 VisitForStackValue(args->at(1)); // value
3010 VisitForAccumulatorValue(args->at(2)); // string 2962 VisitForAccumulatorValue(args->at(2)); // string
3011 __ Pop(value, index); 2963 PopOperands(value, index);
3012 2964
3013 if (FLAG_debug_code) { 2965 if (FLAG_debug_code) {
3014 __ AssertSmi(value, kNonSmiValue); 2966 __ AssertSmi(value, kNonSmiValue);
3015 __ AssertSmi(index, kNonSmiIndex); 2967 __ AssertSmi(index, kNonSmiIndex);
3016 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 2968 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3017 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, 2969 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch,
3018 two_byte_seq_type); 2970 two_byte_seq_type);
3019 } 2971 }
3020 2972
3021 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); 2973 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3069 ZoneList<Expression*>* args = expr->arguments(); 3021 ZoneList<Expression*>* args = expr->arguments();
3070 DCHECK(args->length() == 2); 3022 DCHECK(args->length() == 2);
3071 3023
3072 VisitForStackValue(args->at(0)); 3024 VisitForStackValue(args->at(0));
3073 VisitForAccumulatorValue(args->at(1)); 3025 VisitForAccumulatorValue(args->at(1));
3074 3026
3075 Register object = x1; 3027 Register object = x1;
3076 Register index = x0; 3028 Register index = x0;
3077 Register result = x3; 3029 Register result = x3;
3078 3030
3079 __ Pop(object); 3031 PopOperand(object);
3080 3032
3081 Label need_conversion; 3033 Label need_conversion;
3082 Label index_out_of_range; 3034 Label index_out_of_range;
3083 Label done; 3035 Label done;
3084 StringCharCodeAtGenerator generator(object, 3036 StringCharCodeAtGenerator generator(object,
3085 index, 3037 index,
3086 result, 3038 result,
3087 &need_conversion, 3039 &need_conversion,
3088 &need_conversion, 3040 &need_conversion,
3089 &index_out_of_range, 3041 &index_out_of_range,
(...skipping 24 matching lines...) Expand all
3114 ZoneList<Expression*>* args = expr->arguments(); 3066 ZoneList<Expression*>* args = expr->arguments();
3115 DCHECK(args->length() == 2); 3067 DCHECK(args->length() == 2);
3116 3068
3117 VisitForStackValue(args->at(0)); 3069 VisitForStackValue(args->at(0));
3118 VisitForAccumulatorValue(args->at(1)); 3070 VisitForAccumulatorValue(args->at(1));
3119 3071
3120 Register object = x1; 3072 Register object = x1;
3121 Register index = x0; 3073 Register index = x0;
3122 Register result = x0; 3074 Register result = x0;
3123 3075
3124 __ Pop(object); 3076 PopOperand(object);
3125 3077
3126 Label need_conversion; 3078 Label need_conversion;
3127 Label index_out_of_range; 3079 Label index_out_of_range;
3128 Label done; 3080 Label done;
3129 StringCharAtGenerator generator(object, 3081 StringCharAtGenerator generator(object,
3130 index, 3082 index,
3131 x3, 3083 x3,
3132 result, 3084 result,
3133 &need_conversion, 3085 &need_conversion,
3134 &need_conversion, 3086 &need_conversion,
(...skipping 29 matching lines...) Expand all
3164 for (Expression* const arg : *args) { 3116 for (Expression* const arg : *args) {
3165 VisitForStackValue(arg); 3117 VisitForStackValue(arg);
3166 } 3118 }
3167 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3119 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3168 // Move target to x1. 3120 // Move target to x1.
3169 int const argc = args->length() - 2; 3121 int const argc = args->length() - 2;
3170 __ Peek(x1, (argc + 1) * kXRegSize); 3122 __ Peek(x1, (argc + 1) * kXRegSize);
3171 // Call the target. 3123 // Call the target.
3172 __ Mov(x0, argc); 3124 __ Mov(x0, argc);
3173 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3125 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3126 OperandStackDepthDecrement(argc + 1);
3174 // Restore context register. 3127 // Restore context register.
3175 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3128 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3176 // Discard the function left on TOS. 3129 // Discard the function left on TOS.
3177 context()->DropAndPlug(1, x0); 3130 context()->DropAndPlug(1, x0);
3178 } 3131 }
3179 3132
3180 3133
3181 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3134 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3182 ZoneList<Expression*>* args = expr->arguments(); 3135 ZoneList<Expression*>* args = expr->arguments();
3183 VisitForAccumulatorValue(args->at(0)); 3136 VisitForAccumulatorValue(args->at(0));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3260 __ ObjectUntag(untagged_result, result); 3213 __ ObjectUntag(untagged_result, result);
3261 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); 3214 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset));
3262 __ Stp(empty_fixed_array, empty_fixed_array, 3215 __ Stp(empty_fixed_array, empty_fixed_array,
3263 MemOperand(untagged_result, JSObject::kPropertiesOffset)); 3216 MemOperand(untagged_result, JSObject::kPropertiesOffset));
3264 __ Stp(result_value, boolean_done, 3217 __ Stp(result_value, boolean_done,
3265 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); 3218 MemOperand(untagged_result, JSIteratorResult::kValueOffset));
3266 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3219 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3267 __ B(&done); 3220 __ B(&done);
3268 3221
3269 __ Bind(&runtime); 3222 __ Bind(&runtime);
3270 __ CallRuntime(Runtime::kCreateIterResultObject); 3223 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3271 3224
3272 __ Bind(&done); 3225 __ Bind(&done);
3273 context()->Plug(x0); 3226 context()->Plug(x0);
3274 } 3227 }
3275 3228
3276 3229
3277 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3230 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3278 // Push undefined as the receiver. 3231 // Push undefined as the receiver.
3279 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 3232 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
3280 __ Push(x0); 3233 PushOperand(x0);
3281 3234
3282 __ LoadNativeContextSlot(expr->context_index(), x0); 3235 __ LoadNativeContextSlot(expr->context_index(), x0);
3283 } 3236 }
3284 3237
3285 3238
3286 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3239 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3287 ZoneList<Expression*>* args = expr->arguments(); 3240 ZoneList<Expression*>* args = expr->arguments();
3288 int arg_count = args->length(); 3241 int arg_count = args->length();
3289 3242
3290 SetCallPosition(expr); 3243 SetCallPosition(expr);
3291 __ Peek(x1, (arg_count + 1) * kPointerSize); 3244 __ Peek(x1, (arg_count + 1) * kPointerSize);
3292 __ Mov(x0, arg_count); 3245 __ Mov(x0, arg_count);
3293 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3246 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3294 RelocInfo::CODE_TARGET); 3247 RelocInfo::CODE_TARGET);
3248 OperandStackDepthDecrement(arg_count + 1);
3295 } 3249 }
3296 3250
3297 3251
3298 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3252 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3299 ZoneList<Expression*>* args = expr->arguments(); 3253 ZoneList<Expression*>* args = expr->arguments();
3300 int arg_count = args->length(); 3254 int arg_count = args->length();
3301 3255
3302 if (expr->is_jsruntime()) { 3256 if (expr->is_jsruntime()) {
3303 Comment cmnt(masm_, "[ CallRunTime"); 3257 Comment cmnt(masm_, "[ CallRunTime");
3304 EmitLoadJSRuntimeFunction(expr); 3258 EmitLoadJSRuntimeFunction(expr);
3305 3259
3306 // Push the target function under the receiver. 3260 // Push the target function under the receiver.
3307 __ Pop(x10); 3261 PopOperand(x10);
3308 __ Push(x0, x10); 3262 PushOperands(x0, x10);
3309 3263
3310 for (int i = 0; i < arg_count; i++) { 3264 for (int i = 0; i < arg_count; i++) {
3311 VisitForStackValue(args->at(i)); 3265 VisitForStackValue(args->at(i));
3312 } 3266 }
3313 3267
3314 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3268 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3315 EmitCallJSRuntimeFunction(expr); 3269 EmitCallJSRuntimeFunction(expr);
3316 3270
3317 // Restore context register. 3271 // Restore context register.
3318 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3272 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
(...skipping 13 matching lines...) Expand all
3332 default: { 3286 default: {
3333 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3287 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3334 // Push the arguments ("left-to-right"). 3288 // Push the arguments ("left-to-right").
3335 for (int i = 0; i < arg_count; i++) { 3289 for (int i = 0; i < arg_count; i++) {
3336 VisitForStackValue(args->at(i)); 3290 VisitForStackValue(args->at(i));
3337 } 3291 }
3338 3292
3339 // Call the C runtime function. 3293 // Call the C runtime function.
3340 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3294 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3341 __ CallRuntime(expr->function(), arg_count); 3295 __ CallRuntime(expr->function(), arg_count);
3296 OperandStackDepthDecrement(arg_count);
3342 context()->Plug(x0); 3297 context()->Plug(x0);
3343 } 3298 }
3344 } 3299 }
3345 } 3300 }
3346 } 3301 }
3347 3302
3348 3303
3349 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3304 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3350 switch (expr->op()) { 3305 switch (expr->op()) {
3351 case Token::DELETE: { 3306 case Token::DELETE: {
3352 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3307 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3353 Property* property = expr->expression()->AsProperty(); 3308 Property* property = expr->expression()->AsProperty();
3354 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3309 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3355 3310
3356 if (property != NULL) { 3311 if (property != NULL) {
3357 VisitForStackValue(property->obj()); 3312 VisitForStackValue(property->obj());
3358 VisitForStackValue(property->key()); 3313 VisitForStackValue(property->key());
3359 __ CallRuntime(is_strict(language_mode()) 3314 CallRuntimeWithOperands(is_strict(language_mode())
3360 ? Runtime::kDeleteProperty_Strict 3315 ? Runtime::kDeleteProperty_Strict
3361 : Runtime::kDeleteProperty_Sloppy); 3316 : Runtime::kDeleteProperty_Sloppy);
3362 context()->Plug(x0); 3317 context()->Plug(x0);
3363 } else if (proxy != NULL) { 3318 } else if (proxy != NULL) {
3364 Variable* var = proxy->var(); 3319 Variable* var = proxy->var();
3365 // Delete of an unqualified identifier is disallowed in strict mode but 3320 // Delete of an unqualified identifier is disallowed in strict mode but
3366 // "delete this" is allowed. 3321 // "delete this" is allowed.
3367 bool is_this = var->HasThisName(isolate()); 3322 bool is_this = var->HasThisName(isolate());
3368 DCHECK(is_sloppy(language_mode()) || is_this); 3323 DCHECK(is_sloppy(language_mode()) || is_this);
3369 if (var->IsUnallocatedOrGlobalSlot()) { 3324 if (var->IsUnallocatedOrGlobalSlot()) {
3370 __ LoadGlobalObject(x12); 3325 __ LoadGlobalObject(x12);
3371 __ Mov(x11, Operand(var->name())); 3326 __ Mov(x11, Operand(var->name()));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3414 context()->Plug(test->true_label(), test->false_label()); 3369 context()->Plug(test->true_label(), test->false_label());
3415 } else { 3370 } else {
3416 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3371 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3417 // TODO(jbramley): This could be much more efficient using (for 3372 // TODO(jbramley): This could be much more efficient using (for
3418 // example) the CSEL instruction. 3373 // example) the CSEL instruction.
3419 Label materialize_true, materialize_false, done; 3374 Label materialize_true, materialize_false, done;
3420 VisitForControl(expr->expression(), 3375 VisitForControl(expr->expression(),
3421 &materialize_false, 3376 &materialize_false,
3422 &materialize_true, 3377 &materialize_true,
3423 &materialize_true); 3378 &materialize_true);
3379 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3424 3380
3425 __ Bind(&materialize_true); 3381 __ Bind(&materialize_true);
3426 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3382 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3427 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); 3383 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
3428 __ B(&done); 3384 __ B(&done);
3429 3385
3430 __ Bind(&materialize_false); 3386 __ Bind(&materialize_false);
3431 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3387 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
3432 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); 3388 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
3433 __ B(&done); 3389 __ B(&done);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3466 LhsKind assign_type = Property::GetAssignType(prop); 3422 LhsKind assign_type = Property::GetAssignType(prop);
3467 3423
3468 // Evaluate expression and get value. 3424 // Evaluate expression and get value.
3469 if (assign_type == VARIABLE) { 3425 if (assign_type == VARIABLE) {
3470 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3426 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3471 AccumulatorValueContext context(this); 3427 AccumulatorValueContext context(this);
3472 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3428 EmitVariableLoad(expr->expression()->AsVariableProxy());
3473 } else { 3429 } else {
3474 // Reserve space for result of postfix operation. 3430 // Reserve space for result of postfix operation.
3475 if (expr->is_postfix() && !context()->IsEffect()) { 3431 if (expr->is_postfix() && !context()->IsEffect()) {
3476 __ Push(xzr); 3432 PushOperand(xzr);
3477 } 3433 }
3478 switch (assign_type) { 3434 switch (assign_type) {
3479 case NAMED_PROPERTY: { 3435 case NAMED_PROPERTY: {
3480 // Put the object both on the stack and in the register. 3436 // Put the object both on the stack and in the register.
3481 VisitForStackValue(prop->obj()); 3437 VisitForStackValue(prop->obj());
3482 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 3438 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
3483 EmitNamedPropertyLoad(prop); 3439 EmitNamedPropertyLoad(prop);
3484 break; 3440 break;
3485 } 3441 }
3486 3442
3487 case NAMED_SUPER_PROPERTY: { 3443 case NAMED_SUPER_PROPERTY: {
3488 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3444 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3489 VisitForAccumulatorValue( 3445 VisitForAccumulatorValue(
3490 prop->obj()->AsSuperPropertyReference()->home_object()); 3446 prop->obj()->AsSuperPropertyReference()->home_object());
3491 __ Push(result_register()); 3447 PushOperand(result_register());
3492 const Register scratch = x10; 3448 const Register scratch = x10;
3493 __ Peek(scratch, kPointerSize); 3449 __ Peek(scratch, kPointerSize);
3494 __ Push(scratch, result_register()); 3450 PushOperands(scratch, result_register());
3495 EmitNamedSuperPropertyLoad(prop); 3451 EmitNamedSuperPropertyLoad(prop);
3496 break; 3452 break;
3497 } 3453 }
3498 3454
3499 case KEYED_SUPER_PROPERTY: { 3455 case KEYED_SUPER_PROPERTY: {
3500 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3456 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3501 VisitForStackValue( 3457 VisitForStackValue(
3502 prop->obj()->AsSuperPropertyReference()->home_object()); 3458 prop->obj()->AsSuperPropertyReference()->home_object());
3503 VisitForAccumulatorValue(prop->key()); 3459 VisitForAccumulatorValue(prop->key());
3504 __ Push(result_register()); 3460 PushOperand(result_register());
3505 const Register scratch1 = x10; 3461 const Register scratch1 = x10;
3506 const Register scratch2 = x11; 3462 const Register scratch2 = x11;
3507 __ Peek(scratch1, 2 * kPointerSize); 3463 __ Peek(scratch1, 2 * kPointerSize);
3508 __ Peek(scratch2, kPointerSize); 3464 __ Peek(scratch2, kPointerSize);
3509 __ Push(scratch1, scratch2, result_register()); 3465 PushOperands(scratch1, scratch2, result_register());
3510 EmitKeyedSuperPropertyLoad(prop); 3466 EmitKeyedSuperPropertyLoad(prop);
3511 break; 3467 break;
3512 } 3468 }
3513 3469
3514 case KEYED_PROPERTY: { 3470 case KEYED_PROPERTY: {
3515 VisitForStackValue(prop->obj()); 3471 VisitForStackValue(prop->obj());
3516 VisitForStackValue(prop->key()); 3472 VisitForStackValue(prop->key());
3517 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); 3473 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
3518 __ Peek(LoadDescriptor::NameRegister(), 0); 3474 __ Peek(LoadDescriptor::NameRegister(), 0);
3519 EmitKeyedPropertyLoad(prop); 3475 EmitKeyedPropertyLoad(prop);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3582 } 3538 }
3583 3539
3584 // Save result for postfix expressions. 3540 // Save result for postfix expressions.
3585 if (expr->is_postfix()) { 3541 if (expr->is_postfix()) {
3586 if (!context()->IsEffect()) { 3542 if (!context()->IsEffect()) {
3587 // Save the result on the stack. If we have a named or keyed property 3543 // Save the result on the stack. If we have a named or keyed property
3588 // we store the result under the receiver that is currently on top 3544 // we store the result under the receiver that is currently on top
3589 // of the stack. 3545 // of the stack.
3590 switch (assign_type) { 3546 switch (assign_type) {
3591 case VARIABLE: 3547 case VARIABLE:
3592 __ Push(x0); 3548 PushOperand(x0);
3593 break; 3549 break;
3594 case NAMED_PROPERTY: 3550 case NAMED_PROPERTY:
3595 __ Poke(x0, kXRegSize); 3551 __ Poke(x0, kXRegSize);
3596 break; 3552 break;
3597 case NAMED_SUPER_PROPERTY: 3553 case NAMED_SUPER_PROPERTY:
3598 __ Poke(x0, 2 * kXRegSize); 3554 __ Poke(x0, 2 * kXRegSize);
3599 break; 3555 break;
3600 case KEYED_PROPERTY: 3556 case KEYED_PROPERTY:
3601 __ Poke(x0, 2 * kXRegSize); 3557 __ Poke(x0, 2 * kXRegSize);
3602 break; 3558 break;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3642 } else { 3598 } else {
3643 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3599 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3644 Token::ASSIGN, expr->CountSlot()); 3600 Token::ASSIGN, expr->CountSlot());
3645 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3601 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3646 context()->Plug(x0); 3602 context()->Plug(x0);
3647 } 3603 }
3648 break; 3604 break;
3649 case NAMED_PROPERTY: { 3605 case NAMED_PROPERTY: {
3650 __ Mov(StoreDescriptor::NameRegister(), 3606 __ Mov(StoreDescriptor::NameRegister(),
3651 Operand(prop->key()->AsLiteral()->value())); 3607 Operand(prop->key()->AsLiteral()->value()));
3652 __ Pop(StoreDescriptor::ReceiverRegister()); 3608 PopOperand(StoreDescriptor::ReceiverRegister());
3653 EmitLoadStoreICSlot(expr->CountSlot()); 3609 EmitLoadStoreICSlot(expr->CountSlot());
3654 CallStoreIC(); 3610 CallStoreIC();
3655 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3611 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3656 if (expr->is_postfix()) { 3612 if (expr->is_postfix()) {
3657 if (!context()->IsEffect()) { 3613 if (!context()->IsEffect()) {
3658 context()->PlugTOS(); 3614 context()->PlugTOS();
3659 } 3615 }
3660 } else { 3616 } else {
3661 context()->Plug(x0); 3617 context()->Plug(x0);
3662 } 3618 }
(...skipping 15 matching lines...) Expand all
3678 if (expr->is_postfix()) { 3634 if (expr->is_postfix()) {
3679 if (!context()->IsEffect()) { 3635 if (!context()->IsEffect()) {
3680 context()->PlugTOS(); 3636 context()->PlugTOS();
3681 } 3637 }
3682 } else { 3638 } else {
3683 context()->Plug(x0); 3639 context()->Plug(x0);
3684 } 3640 }
3685 break; 3641 break;
3686 } 3642 }
3687 case KEYED_PROPERTY: { 3643 case KEYED_PROPERTY: {
3688 __ Pop(StoreDescriptor::NameRegister()); 3644 PopOperand(StoreDescriptor::NameRegister());
3689 __ Pop(StoreDescriptor::ReceiverRegister()); 3645 PopOperand(StoreDescriptor::ReceiverRegister());
3690 Handle<Code> ic = 3646 Handle<Code> ic =
3691 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3647 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3692 EmitLoadStoreICSlot(expr->CountSlot()); 3648 EmitLoadStoreICSlot(expr->CountSlot());
3693 CallIC(ic); 3649 CallIC(ic);
3694 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3650 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3695 if (expr->is_postfix()) { 3651 if (expr->is_postfix()) {
3696 if (!context()->IsEffect()) { 3652 if (!context()->IsEffect()) {
3697 context()->PlugTOS(); 3653 context()->PlugTOS();
3698 } 3654 }
3699 } else { 3655 } else {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3810 Label* if_false = NULL; 3766 Label* if_false = NULL;
3811 Label* fall_through = NULL; 3767 Label* fall_through = NULL;
3812 context()->PrepareTest(&materialize_true, &materialize_false, 3768 context()->PrepareTest(&materialize_true, &materialize_false,
3813 &if_true, &if_false, &fall_through); 3769 &if_true, &if_false, &fall_through);
3814 3770
3815 Token::Value op = expr->op(); 3771 Token::Value op = expr->op();
3816 VisitForStackValue(expr->left()); 3772 VisitForStackValue(expr->left());
3817 switch (op) { 3773 switch (op) {
3818 case Token::IN: 3774 case Token::IN:
3819 VisitForStackValue(expr->right()); 3775 VisitForStackValue(expr->right());
3820 __ CallRuntime(Runtime::kHasProperty); 3776 CallRuntimeWithOperands(Runtime::kHasProperty);
3821 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3777 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3822 __ CompareRoot(x0, Heap::kTrueValueRootIndex); 3778 __ CompareRoot(x0, Heap::kTrueValueRootIndex);
3823 Split(eq, if_true, if_false, fall_through); 3779 Split(eq, if_true, if_false, fall_through);
3824 break; 3780 break;
3825 3781
3826 case Token::INSTANCEOF: { 3782 case Token::INSTANCEOF: {
3827 VisitForAccumulatorValue(expr->right()); 3783 VisitForAccumulatorValue(expr->right());
3828 __ Pop(x1); 3784 PopOperand(x1);
3829 InstanceOfStub stub(isolate()); 3785 InstanceOfStub stub(isolate());
3830 __ CallStub(&stub); 3786 __ CallStub(&stub);
3831 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3787 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3832 __ CompareRoot(x0, Heap::kTrueValueRootIndex); 3788 __ CompareRoot(x0, Heap::kTrueValueRootIndex);
3833 Split(eq, if_true, if_false, fall_through); 3789 Split(eq, if_true, if_false, fall_through);
3834 break; 3790 break;
3835 } 3791 }
3836 3792
3837 default: { 3793 default: {
3838 VisitForAccumulatorValue(expr->right()); 3794 VisitForAccumulatorValue(expr->right());
3839 Condition cond = CompareIC::ComputeCondition(op); 3795 Condition cond = CompareIC::ComputeCondition(op);
3840 3796
3841 // Pop the stack value. 3797 // Pop the stack value.
3842 __ Pop(x1); 3798 PopOperand(x1);
3843 3799
3844 JumpPatchSite patch_site(masm_); 3800 JumpPatchSite patch_site(masm_);
3845 if (ShouldInlineSmiCase(op)) { 3801 if (ShouldInlineSmiCase(op)) {
3846 Label slow_case; 3802 Label slow_case;
3847 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); 3803 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case);
3848 __ Cmp(x1, x0); 3804 __ Cmp(x1, x0);
3849 Split(cond, if_true, if_false, NULL); 3805 Split(cond, if_true, if_false, NULL);
3850 __ Bind(&slow_case); 3806 __ Bind(&slow_case);
3851 } 3807 }
3852 3808
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
3947 __ Mov(x1, cp); 3903 __ Mov(x1, cp);
3948 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, 3904 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2,
3949 kLRHasBeenSaved, kDontSaveFPRegs); 3905 kLRHasBeenSaved, kDontSaveFPRegs);
3950 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); 3906 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset);
3951 __ Cmp(__ StackPointer(), x1); 3907 __ Cmp(__ StackPointer(), x1);
3952 __ B(eq, &post_runtime); 3908 __ B(eq, &post_runtime);
3953 __ Push(x0); // generator object 3909 __ Push(x0); // generator object
3954 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 3910 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
3955 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3911 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3956 __ Bind(&post_runtime); 3912 __ Bind(&post_runtime);
3957 __ Pop(result_register()); 3913 PopOperand(result_register());
3958 EmitReturnSequence(); 3914 EmitReturnSequence();
3959 3915
3960 __ Bind(&resume); 3916 __ Bind(&resume);
3961 context()->Plug(result_register()); 3917 context()->Plug(result_register());
3962 break; 3918 break;
3963 } 3919 }
3964 3920
3965 case Yield::kFinal: { 3921 case Yield::kFinal: {
3966 // Pop value from top-of-stack slot, box result into result register. 3922 // Pop value from top-of-stack slot, box result into result register.
3923 OperandStackDepthDecrement(1);
3967 EmitCreateIteratorResult(true); 3924 EmitCreateIteratorResult(true);
3968 EmitUnwindAndReturn(); 3925 EmitUnwindAndReturn();
3969 break; 3926 break;
3970 } 3927 }
3971 3928
3972 case Yield::kDelegating: 3929 case Yield::kDelegating:
3973 UNREACHABLE(); 3930 UNREACHABLE();
3974 } 3931 }
3975 } 3932 }
3976 3933
3977 3934
3978 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 3935 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
3979 Expression *value, 3936 Expression *value,
3980 JSGeneratorObject::ResumeMode resume_mode) { 3937 JSGeneratorObject::ResumeMode resume_mode) {
3981 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); 3938 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume");
3982 Register generator_object = x1; 3939 Register generator_object = x1;
3983 Register the_hole = x2; 3940 Register the_hole = x2;
3984 Register operand_stack_size = w3; 3941 Register operand_stack_size = w3;
3985 Register function = x4; 3942 Register function = x4;
3986 3943
3987 // The value stays in x0, and is ultimately read by the resumed generator, as 3944 // The value stays in x0, and is ultimately read by the resumed generator, as
3988 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 3945 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
3989 // is read to throw the value when the resumed generator is already closed. x1 3946 // is read to throw the value when the resumed generator is already closed. x1
3990 // will hold the generator object until the activation has been resumed. 3947 // will hold the generator object until the activation has been resumed.
3991 VisitForStackValue(generator); 3948 VisitForStackValue(generator);
3992 VisitForAccumulatorValue(value); 3949 VisitForAccumulatorValue(value);
3993 __ Pop(generator_object); 3950 PopOperand(generator_object);
3994 3951
3995 // Store input value into generator object. 3952 // Store input value into generator object.
3996 __ Str(result_register(), 3953 __ Str(result_register(),
3997 FieldMemOperand(x1, JSGeneratorObject::kInputOffset)); 3954 FieldMemOperand(x1, JSGeneratorObject::kInputOffset));
3998 __ Mov(x2, result_register()); 3955 __ Mov(x2, result_register());
3999 __ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x2, x3, 3956 __ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x2, x3,
4000 kLRHasBeenSaved, kDontSaveFPRegs); 3957 kLRHasBeenSaved, kDontSaveFPRegs);
4001 3958
4002 // Load suspended function and context. 3959 // Load suspended function and context.
4003 __ Ldr(cp, FieldMemOperand(generator_object, 3960 __ Ldr(cp, FieldMemOperand(generator_object,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
4068 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. 4025 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
4069 __ Push(generator_object, result_register(), x10); 4026 __ Push(generator_object, result_register(), x10);
4070 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 4027 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
4071 // Not reached: the runtime call returns elsewhere. 4028 // Not reached: the runtime call returns elsewhere.
4072 __ Unreachable(); 4029 __ Unreachable();
4073 4030
4074 __ Bind(&done); 4031 __ Bind(&done);
4075 context()->Plug(result_register()); 4032 context()->Plug(result_register());
4076 } 4033 }
4077 4034
4035 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
4036 OperandStackDepthIncrement(2);
4037 __ Push(reg1, reg2);
4038 }
4039
4040 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
4041 Register reg3) {
4042 OperandStackDepthIncrement(3);
4043 __ Push(reg1, reg2, reg3);
4044 }
4045
4046 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) {
4047 OperandStackDepthDecrement(2);
4048 __ Pop(reg1, reg2);
4049 }
4050
4051 void FullCodeGenerator::EmitOperandStackDepthCheck() {
4052 if (FLAG_debug_code) {
4053 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
4054 operand_stack_depth_ * kPointerSize;
4055 __ Sub(x0, fp, jssp);
4056 __ Cmp(x0, Operand(expected_diff));
4057 __ Assert(eq, kUnexpectedStackDepth);
4058 }
4059 }
4078 4060
4079 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 4061 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
4080 Label allocate, done_allocate; 4062 Label allocate, done_allocate;
4081 4063
4082 // Allocate and populate an object with this form: { value: VAL, done: DONE } 4064 // Allocate and populate an object with this form: { value: VAL, done: DONE }
4083 4065
4084 Register result = x0; 4066 Register result = x0;
4085 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &allocate, TAG_OBJECT); 4067 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &allocate, TAG_OBJECT);
4086 __ B(&done_allocate); 4068 __ B(&done_allocate);
4087 4069
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4155 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, x10); 4137 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, x10);
4156 } else if (closure_scope->is_eval_scope()) { 4138 } else if (closure_scope->is_eval_scope()) {
4157 // Contexts created by a call to eval have the same closure as the 4139 // Contexts created by a call to eval have the same closure as the
4158 // context calling eval, not the anonymous closure containing the eval 4140 // context calling eval, not the anonymous closure containing the eval
4159 // code. Fetch it from the context. 4141 // code. Fetch it from the context.
4160 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); 4142 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX));
4161 } else { 4143 } else {
4162 DCHECK(closure_scope->is_function_scope()); 4144 DCHECK(closure_scope->is_function_scope());
4163 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4145 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4164 } 4146 }
4165 __ Push(x10); 4147 PushOperand(x10);
4166 } 4148 }
4167 4149
4168 4150
4169 void FullCodeGenerator::EnterFinallyBlock() { 4151 void FullCodeGenerator::EnterFinallyBlock() {
4170 ASM_LOCATION("FullCodeGenerator::EnterFinallyBlock"); 4152 ASM_LOCATION("FullCodeGenerator::EnterFinallyBlock");
4171 DCHECK(!result_register().is(x10)); 4153 DCHECK(!result_register().is(x10));
4172 // Store pending message while executing finally block. 4154 // Store pending message while executing finally block.
4173 ExternalReference pending_message_obj = 4155 ExternalReference pending_message_obj =
4174 ExternalReference::address_of_pending_message_obj(isolate()); 4156 ExternalReference::address_of_pending_message_obj(isolate());
4175 __ Mov(x10, pending_message_obj); 4157 __ Mov(x10, pending_message_obj);
4176 __ Ldr(x10, MemOperand(x10)); 4158 __ Ldr(x10, MemOperand(x10));
4177 __ Push(x10); 4159 PushOperand(x10);
4178 4160
4179 ClearPendingMessage(); 4161 ClearPendingMessage();
4180 } 4162 }
4181 4163
4182 4164
4183 void FullCodeGenerator::ExitFinallyBlock() { 4165 void FullCodeGenerator::ExitFinallyBlock() {
4184 ASM_LOCATION("FullCodeGenerator::ExitFinallyBlock"); 4166 ASM_LOCATION("FullCodeGenerator::ExitFinallyBlock");
4185 DCHECK(!result_register().is(x10)); 4167 DCHECK(!result_register().is(x10));
4186 4168
4187 // Restore pending message from stack. 4169 // Restore pending message from stack.
4188 __ Pop(x10); 4170 PopOperand(x10);
4189 ExternalReference pending_message_obj = 4171 ExternalReference pending_message_obj =
4190 ExternalReference::address_of_pending_message_obj(isolate()); 4172 ExternalReference::address_of_pending_message_obj(isolate());
4191 __ Mov(x13, pending_message_obj); 4173 __ Mov(x13, pending_message_obj);
4192 __ Str(x10, MemOperand(x13)); 4174 __ Str(x10, MemOperand(x13));
4193 } 4175 }
4194 4176
4195 4177
4196 void FullCodeGenerator::ClearPendingMessage() { 4178 void FullCodeGenerator::ClearPendingMessage() {
4197 DCHECK(!result_register().is(x10)); 4179 DCHECK(!result_register().is(x10));
4198 ExternalReference pending_message_obj = 4180 ExternalReference pending_message_obj =
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4321 } 4303 }
4322 4304
4323 return INTERRUPT; 4305 return INTERRUPT;
4324 } 4306 }
4325 4307
4326 4308
4327 } // namespace internal 4309 } // namespace internal
4328 } // namespace v8 4310 } // namespace v8
4329 4311
4330 #endif // V8_TARGET_ARCH_ARM64 4312 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/full-codegen/arm/full-codegen-arm.cc ('k') | src/full-codegen/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698