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

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

Powered by Google App Engine
This is Rietveld 408576698