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

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

Issue 1729613002: PPC: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_PPC 5 #if V8_TARGET_ARCH_PPC
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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 __ addi(ip, ip, Operand(prologue_offset)); 129 __ addi(ip, ip, Operand(prologue_offset));
130 } 130 }
131 info->set_prologue_offset(prologue_offset); 131 info->set_prologue_offset(prologue_offset);
132 __ Prologue(info->GeneratePreagedPrologue(), ip, prologue_offset); 132 __ Prologue(info->GeneratePreagedPrologue(), ip, prologue_offset);
133 133
134 { 134 {
135 Comment cmnt(masm_, "[ Allocate locals"); 135 Comment cmnt(masm_, "[ Allocate locals");
136 int locals_count = info->scope()->num_stack_slots(); 136 int locals_count = info->scope()->num_stack_slots();
137 // Generators allocate locals, if any, in context slots. 137 // Generators allocate locals, if any, in context slots.
138 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 138 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
139 OperandStackDepthIncrement(locals_count);
139 if (locals_count > 0) { 140 if (locals_count > 0) {
140 if (locals_count >= 128) { 141 if (locals_count >= 128) {
141 Label ok; 142 Label ok;
142 __ Add(ip, sp, -(locals_count * kPointerSize), r0); 143 __ Add(ip, sp, -(locals_count * kPointerSize), r0);
143 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex); 144 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
144 __ cmpl(ip, r5); 145 __ cmpl(ip, r5);
145 __ bc_short(ge, &ok); 146 __ bc_short(ge, &ok);
146 __ CallRuntime(Runtime::kThrowStackOverflow); 147 __ CallRuntime(Runtime::kThrowStackOverflow);
147 __ bind(&ok); 148 __ bind(&ok);
148 } 149 }
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); 454 __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta);
454 __ blr(); 455 __ blr();
455 } 456 }
456 } 457 }
457 } 458 }
458 459
459 460
460 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 461 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
461 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 462 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
462 codegen()->GetVar(result_register(), var); 463 codegen()->GetVar(result_register(), var);
463 __ push(result_register()); 464 codegen()->PushOperand(result_register());
464 } 465 }
465 466
466 467
467 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} 468 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {}
468 469
469 470
470 void FullCodeGenerator::AccumulatorValueContext::Plug( 471 void FullCodeGenerator::AccumulatorValueContext::Plug(
471 Heap::RootListIndex index) const { 472 Heap::RootListIndex index) const {
472 __ LoadRoot(result_register(), index); 473 __ LoadRoot(result_register(), index);
473 } 474 }
474 475
475 476
476 void FullCodeGenerator::StackValueContext::Plug( 477 void FullCodeGenerator::StackValueContext::Plug(
477 Heap::RootListIndex index) const { 478 Heap::RootListIndex index) const {
478 __ LoadRoot(result_register(), index); 479 __ LoadRoot(result_register(), index);
479 __ push(result_register()); 480 codegen()->PushOperand(result_register());
480 } 481 }
481 482
482 483
483 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 484 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
484 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, 485 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
485 false_label_); 486 false_label_);
486 if (index == Heap::kUndefinedValueRootIndex || 487 if (index == Heap::kUndefinedValueRootIndex ||
487 index == Heap::kNullValueRootIndex || 488 index == Heap::kNullValueRootIndex ||
488 index == Heap::kFalseValueRootIndex) { 489 index == Heap::kFalseValueRootIndex) {
489 if (false_label_ != fall_through_) __ b(false_label_); 490 if (false_label_ != fall_through_) __ b(false_label_);
(...skipping 11 matching lines...) Expand all
501 502
502 void FullCodeGenerator::AccumulatorValueContext::Plug( 503 void FullCodeGenerator::AccumulatorValueContext::Plug(
503 Handle<Object> lit) const { 504 Handle<Object> lit) const {
504 __ mov(result_register(), Operand(lit)); 505 __ mov(result_register(), Operand(lit));
505 } 506 }
506 507
507 508
508 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 509 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
509 // Immediates cannot be pushed directly. 510 // Immediates cannot be pushed directly.
510 __ mov(result_register(), Operand(lit)); 511 __ mov(result_register(), Operand(lit));
511 __ push(result_register()); 512 codegen()->PushOperand(result_register());
512 } 513 }
513 514
514 515
515 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 516 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
516 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, 517 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
517 false_label_); 518 false_label_);
518 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); 519 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject());
519 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 520 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
520 if (false_label_ != fall_through_) __ b(false_label_); 521 if (false_label_ != fall_through_) __ b(false_label_);
521 } else if (lit->IsTrue() || lit->IsJSObject()) { 522 } else if (lit->IsTrue() || lit->IsJSObject()) {
(...skipping 14 matching lines...) Expand all
536 // For simplicity we always test the accumulator register. 537 // For simplicity we always test the accumulator register.
537 __ mov(result_register(), Operand(lit)); 538 __ mov(result_register(), Operand(lit));
538 codegen()->DoTest(this); 539 codegen()->DoTest(this);
539 } 540 }
540 } 541 }
541 542
542 543
543 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 544 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
544 Register reg) const { 545 Register reg) const {
545 DCHECK(count > 0); 546 DCHECK(count > 0);
546 if (count > 1) __ Drop(count - 1); 547 if (count > 1) codegen()->DropOperands(count - 1);
547 __ StoreP(reg, MemOperand(sp, 0)); 548 __ StoreP(reg, MemOperand(sp, 0));
548 } 549 }
549 550
550 551
551 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 552 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
552 Label* materialize_false) const { 553 Label* materialize_false) const {
553 DCHECK(materialize_true == materialize_false); 554 DCHECK(materialize_true == materialize_false);
554 __ bind(materialize_true); 555 __ bind(materialize_true);
555 } 556 }
556 557
(...skipping 12 matching lines...) Expand all
569 570
570 void FullCodeGenerator::StackValueContext::Plug( 571 void FullCodeGenerator::StackValueContext::Plug(
571 Label* materialize_true, Label* materialize_false) const { 572 Label* materialize_true, Label* materialize_false) const {
572 Label done; 573 Label done;
573 __ bind(materialize_true); 574 __ bind(materialize_true);
574 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 575 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
575 __ b(&done); 576 __ b(&done);
576 __ bind(materialize_false); 577 __ bind(materialize_false);
577 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 578 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
578 __ bind(&done); 579 __ bind(&done);
579 __ push(ip); 580 codegen()->PushOperand(ip);
580 } 581 }
581 582
582 583
583 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 584 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
584 Label* materialize_false) const { 585 Label* materialize_false) const {
585 DCHECK(materialize_true == true_label_); 586 DCHECK(materialize_true == true_label_);
586 DCHECK(materialize_false == false_label_); 587 DCHECK(materialize_false == false_label_);
587 } 588 }
588 589
589 590
590 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 591 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
591 Heap::RootListIndex value_root_index = 592 Heap::RootListIndex value_root_index =
592 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 593 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
593 __ LoadRoot(result_register(), value_root_index); 594 __ LoadRoot(result_register(), value_root_index);
594 } 595 }
595 596
596 597
597 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 598 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
598 Heap::RootListIndex value_root_index = 599 Heap::RootListIndex value_root_index =
599 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 600 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
600 __ LoadRoot(ip, value_root_index); 601 __ LoadRoot(ip, value_root_index);
601 __ push(ip); 602 codegen()->PushOperand(ip);
602 } 603 }
603 604
604 605
605 void FullCodeGenerator::TestContext::Plug(bool flag) const { 606 void FullCodeGenerator::TestContext::Plug(bool flag) const {
606 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, 607 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
607 false_label_); 608 false_label_);
608 if (flag) { 609 if (flag) {
609 if (true_label_ != fall_through_) __ b(true_label_); 610 if (true_label_ != fall_through_) __ b(true_label_);
610 } else { 611 } else {
611 if (false_label_ != fall_through_) __ b(false_label_); 612 if (false_label_ != fall_through_) __ b(false_label_);
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 __ RecordWriteContextSlot(cp, offset, result_register(), r5, 819 __ RecordWriteContextSlot(cp, offset, result_register(), r5,
819 kLRHasBeenSaved, kDontSaveFPRegs, 820 kLRHasBeenSaved, kDontSaveFPRegs,
820 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 821 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
821 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 822 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
822 break; 823 break;
823 } 824 }
824 825
825 case VariableLocation::LOOKUP: { 826 case VariableLocation::LOOKUP: {
826 Comment cmnt(masm_, "[ FunctionDeclaration"); 827 Comment cmnt(masm_, "[ FunctionDeclaration");
827 __ mov(r5, Operand(variable->name())); 828 __ mov(r5, Operand(variable->name()));
828 __ Push(r5); 829 PushOperand(r5);
829 // Push initial value for function declaration. 830 // Push initial value for function declaration.
830 VisitForStackValue(declaration->fun()); 831 VisitForStackValue(declaration->fun());
831 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 832 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
832 __ CallRuntime(Runtime::kDeclareLookupSlot); 833 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
833 break; 834 break;
834 } 835 }
835 } 836 }
836 } 837 }
837 838
838 839
839 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 840 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
840 // Call the runtime to declare the globals. 841 // Call the runtime to declare the globals.
841 __ mov(r4, Operand(pairs)); 842 __ mov(r4, Operand(pairs));
842 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags())); 843 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 921
921 __ cmpi(r3, Operand::Zero()); 922 __ cmpi(r3, Operand::Zero());
922 __ bne(&next_test); 923 __ bne(&next_test);
923 __ Drop(1); // Switch value is no longer needed. 924 __ Drop(1); // Switch value is no longer needed.
924 __ b(clause->body_target()); 925 __ b(clause->body_target());
925 } 926 }
926 927
927 // Discard the test value and jump to the default if present, otherwise to 928 // Discard the test value and jump to the default if present, otherwise to
928 // the end of the statement. 929 // the end of the statement.
929 __ bind(&next_test); 930 __ bind(&next_test);
930 __ Drop(1); // Switch value is no longer needed. 931 DropOperands(1); // Switch value is no longer needed.
931 if (default_clause == NULL) { 932 if (default_clause == NULL) {
932 __ b(nested_statement.break_label()); 933 __ b(nested_statement.break_label());
933 } else { 934 } else {
934 __ b(default_clause->body_target()); 935 __ b(default_clause->body_target());
935 } 936 }
936 937
937 // Compile all the case bodies. 938 // Compile all the case bodies.
938 for (int i = 0; i < clauses->length(); i++) { 939 for (int i = 0; i < clauses->length(); i++) {
939 Comment cmnt(masm_, "[ Case body"); 940 Comment cmnt(masm_, "[ Case body");
940 CaseClause* clause = clauses->at(i); 941 CaseClause* clause = clauses->at(i);
(...skipping 13 matching lines...) Expand all
954 955
955 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 956 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
956 957
957 Label loop, exit; 958 Label loop, exit;
958 ForIn loop_statement(this, stmt); 959 ForIn loop_statement(this, stmt);
959 increment_loop_depth(); 960 increment_loop_depth();
960 961
961 // Get the object to enumerate over. 962 // Get the object to enumerate over.
962 SetExpressionAsStatementPosition(stmt->enumerable()); 963 SetExpressionAsStatementPosition(stmt->enumerable());
963 VisitForAccumulatorValue(stmt->enumerable()); 964 VisitForAccumulatorValue(stmt->enumerable());
965 OperandStackDepthIncrement(ForIn::kElementCount);
964 966
965 // If the object is null or undefined, skip over the loop, otherwise convert 967 // If the object is null or undefined, skip over the loop, otherwise convert
966 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 968 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
967 Label convert, done_convert; 969 Label convert, done_convert;
968 __ JumpIfSmi(r3, &convert); 970 __ JumpIfSmi(r3, &convert);
969 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); 971 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE);
970 __ bge(&done_convert); 972 __ bge(&done_convert);
971 __ CompareRoot(r3, Heap::kNullValueRootIndex); 973 __ CompareRoot(r3, Heap::kNullValueRootIndex);
972 __ beq(&exit); 974 __ beq(&exit);
973 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); 975 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 __ bind(loop_statement.continue_label()); 1122 __ bind(loop_statement.continue_label());
1121 __ pop(r3); 1123 __ pop(r3);
1122 __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0); 1124 __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0);
1123 __ push(r3); 1125 __ push(r3);
1124 1126
1125 EmitBackEdgeBookkeeping(stmt, &loop); 1127 EmitBackEdgeBookkeeping(stmt, &loop);
1126 __ b(&loop); 1128 __ b(&loop);
1127 1129
1128 // Remove the pointers stored on the stack. 1130 // Remove the pointers stored on the stack.
1129 __ bind(loop_statement.break_label()); 1131 __ bind(loop_statement.break_label());
1130 __ Drop(5); 1132 DropOperands(5);
1131 1133
1132 // Exit and decrement the loop depth. 1134 // Exit and decrement the loop depth.
1133 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1135 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1134 __ bind(&exit); 1136 __ bind(&exit);
1135 decrement_loop_depth(); 1137 decrement_loop_depth();
1136 } 1138 }
1137 1139
1138 1140
1139 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1141 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1140 bool pretenure) { 1142 bool pretenure) {
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 FastCloneRegExpStub stub(isolate()); 1392 FastCloneRegExpStub stub(isolate());
1391 __ CallStub(&stub); 1393 __ CallStub(&stub);
1392 context()->Plug(r3); 1394 context()->Plug(r3);
1393 } 1395 }
1394 1396
1395 1397
1396 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1398 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1397 Expression* expression = (property == NULL) ? NULL : property->value(); 1399 Expression* expression = (property == NULL) ? NULL : property->value();
1398 if (expression == NULL) { 1400 if (expression == NULL) {
1399 __ LoadRoot(r4, Heap::kNullValueRootIndex); 1401 __ LoadRoot(r4, Heap::kNullValueRootIndex);
1400 __ push(r4); 1402 PushOperand(r4);
1401 } else { 1403 } else {
1402 VisitForStackValue(expression); 1404 VisitForStackValue(expression);
1403 if (NeedsHomeObject(expression)) { 1405 if (NeedsHomeObject(expression)) {
1404 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1406 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1405 property->kind() == ObjectLiteral::Property::SETTER); 1407 property->kind() == ObjectLiteral::Property::SETTER);
1406 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1408 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1407 EmitSetHomeObject(expression, offset, property->GetSlot()); 1409 EmitSetHomeObject(expression, offset, property->GetSlot());
1408 } 1410 }
1409 } 1411 }
1410 } 1412 }
(...skipping 24 matching lines...) Expand all
1435 AccessorTable accessor_table(zone()); 1437 AccessorTable accessor_table(zone());
1436 int property_index = 0; 1438 int property_index = 0;
1437 for (; property_index < expr->properties()->length(); property_index++) { 1439 for (; property_index < expr->properties()->length(); property_index++) {
1438 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1440 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1439 if (property->is_computed_name()) break; 1441 if (property->is_computed_name()) break;
1440 if (property->IsCompileTimeValue()) continue; 1442 if (property->IsCompileTimeValue()) continue;
1441 1443
1442 Literal* key = property->key()->AsLiteral(); 1444 Literal* key = property->key()->AsLiteral();
1443 Expression* value = property->value(); 1445 Expression* value = property->value();
1444 if (!result_saved) { 1446 if (!result_saved) {
1445 __ push(r3); // Save result on stack 1447 PushOperand(r3); // Save result on stack
1446 result_saved = true; 1448 result_saved = true;
1447 } 1449 }
1448 switch (property->kind()) { 1450 switch (property->kind()) {
1449 case ObjectLiteral::Property::CONSTANT: 1451 case ObjectLiteral::Property::CONSTANT:
1450 UNREACHABLE(); 1452 UNREACHABLE();
1451 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1453 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1452 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1454 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1453 // Fall through. 1455 // Fall through.
1454 case ObjectLiteral::Property::COMPUTED: 1456 case ObjectLiteral::Property::COMPUTED:
1455 // It is safe to use [[Put]] here because the boilerplate already 1457 // It is safe to use [[Put]] here because the boilerplate already
(...skipping 11 matching lines...) Expand all
1467 if (NeedsHomeObject(value)) { 1469 if (NeedsHomeObject(value)) {
1468 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1470 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1469 } 1471 }
1470 } else { 1472 } else {
1471 VisitForEffect(value); 1473 VisitForEffect(value);
1472 } 1474 }
1473 break; 1475 break;
1474 } 1476 }
1475 // Duplicate receiver on stack. 1477 // Duplicate receiver on stack.
1476 __ LoadP(r3, MemOperand(sp)); 1478 __ LoadP(r3, MemOperand(sp));
1477 __ push(r3); 1479 PushOperand(r3);
1478 VisitForStackValue(key); 1480 VisitForStackValue(key);
1479 VisitForStackValue(value); 1481 VisitForStackValue(value);
1480 if (property->emit_store()) { 1482 if (property->emit_store()) {
1481 if (NeedsHomeObject(value)) { 1483 if (NeedsHomeObject(value)) {
1482 EmitSetHomeObject(value, 2, property->GetSlot()); 1484 EmitSetHomeObject(value, 2, property->GetSlot());
1483 } 1485 }
1484 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes 1486 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes
1485 __ push(r3); 1487 PushOperand(r3);
1486 __ CallRuntime(Runtime::kSetProperty); 1488 CallRuntimeWithOperands(Runtime::kSetProperty);
1487 } else { 1489 } else {
1488 __ Drop(3); 1490 DropOperands(3);
1489 } 1491 }
1490 break; 1492 break;
1491 case ObjectLiteral::Property::PROTOTYPE: 1493 case ObjectLiteral::Property::PROTOTYPE:
1492 // Duplicate receiver on stack. 1494 // Duplicate receiver on stack.
1493 __ LoadP(r3, MemOperand(sp)); 1495 __ LoadP(r3, MemOperand(sp));
1494 __ push(r3); 1496 PushOperand(r3);
1495 VisitForStackValue(value); 1497 VisitForStackValue(value);
1496 DCHECK(property->emit_store()); 1498 DCHECK(property->emit_store());
1497 __ CallRuntime(Runtime::kInternalSetPrototype); 1499 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1498 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1500 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1499 NO_REGISTERS); 1501 NO_REGISTERS);
1500 break; 1502 break;
1501 case ObjectLiteral::Property::GETTER: 1503 case ObjectLiteral::Property::GETTER:
1502 if (property->emit_store()) { 1504 if (property->emit_store()) {
1503 accessor_table.lookup(key)->second->getter = property; 1505 accessor_table.lookup(key)->second->getter = property;
1504 } 1506 }
1505 break; 1507 break;
1506 case ObjectLiteral::Property::SETTER: 1508 case ObjectLiteral::Property::SETTER:
1507 if (property->emit_store()) { 1509 if (property->emit_store()) {
1508 accessor_table.lookup(key)->second->setter = property; 1510 accessor_table.lookup(key)->second->setter = property;
1509 } 1511 }
1510 break; 1512 break;
1511 } 1513 }
1512 } 1514 }
1513 1515
1514 // Emit code to define accessors, using only a single call to the runtime for 1516 // Emit code to define accessors, using only a single call to the runtime for
1515 // each pair of corresponding getters and setters. 1517 // each pair of corresponding getters and setters.
1516 for (AccessorTable::Iterator it = accessor_table.begin(); 1518 for (AccessorTable::Iterator it = accessor_table.begin();
1517 it != accessor_table.end(); ++it) { 1519 it != accessor_table.end(); ++it) {
1518 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. 1520 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
1519 __ push(r3); 1521 PushOperand(r3);
1520 VisitForStackValue(it->first); 1522 VisitForStackValue(it->first);
1521 EmitAccessor(it->second->getter); 1523 EmitAccessor(it->second->getter);
1522 EmitAccessor(it->second->setter); 1524 EmitAccessor(it->second->setter);
1523 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); 1525 __ LoadSmiLiteral(r3, Smi::FromInt(NONE));
1524 __ push(r3); 1526 PushOperand(r3);
1525 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1527 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1526 } 1528 }
1527 1529
1528 // Object literals have two parts. The "static" part on the left contains no 1530 // Object literals have two parts. The "static" part on the left contains no
1529 // computed property names, and so we can compute its map ahead of time; see 1531 // computed property names, and so we can compute its map ahead of time; see
1530 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1532 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1531 // starts with the first computed property name, and continues with all 1533 // starts with the first computed property name, and continues with all
1532 // properties to its right. All the code from above initializes the static 1534 // properties to its right. All the code from above initializes the static
1533 // component of the object literal, and arranges for the map of the result to 1535 // component of the object literal, and arranges for the map of the result to
1534 // reflect the static order in which the keys appear. For the dynamic 1536 // reflect the static order in which the keys appear. For the dynamic
1535 // properties, we compile them into a series of "SetOwnProperty" runtime 1537 // properties, we compile them into a series of "SetOwnProperty" runtime
1536 // calls. This will preserve insertion order. 1538 // calls. This will preserve insertion order.
1537 for (; property_index < expr->properties()->length(); property_index++) { 1539 for (; property_index < expr->properties()->length(); property_index++) {
1538 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1540 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1539 1541
1540 Expression* value = property->value(); 1542 Expression* value = property->value();
1541 if (!result_saved) { 1543 if (!result_saved) {
1542 __ push(r3); // Save result on the stack 1544 PushOperand(r3); // Save result on the stack
1543 result_saved = true; 1545 result_saved = true;
1544 } 1546 }
1545 1547
1546 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. 1548 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
1547 __ push(r3); 1549 PushOperand(r3);
1548 1550
1549 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1551 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1550 DCHECK(!property->is_computed_name()); 1552 DCHECK(!property->is_computed_name());
1551 VisitForStackValue(value); 1553 VisitForStackValue(value);
1552 DCHECK(property->emit_store()); 1554 DCHECK(property->emit_store());
1553 __ CallRuntime(Runtime::kInternalSetPrototype); 1555 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1554 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1556 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1555 NO_REGISTERS); 1557 NO_REGISTERS);
1556 } else { 1558 } else {
1557 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1559 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1558 VisitForStackValue(value); 1560 VisitForStackValue(value);
1559 if (NeedsHomeObject(value)) { 1561 if (NeedsHomeObject(value)) {
1560 EmitSetHomeObject(value, 2, property->GetSlot()); 1562 EmitSetHomeObject(value, 2, property->GetSlot());
1561 } 1563 }
1562 1564
1563 switch (property->kind()) { 1565 switch (property->kind()) {
1564 case ObjectLiteral::Property::CONSTANT: 1566 case ObjectLiteral::Property::CONSTANT:
1565 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1567 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1566 case ObjectLiteral::Property::COMPUTED: 1568 case ObjectLiteral::Property::COMPUTED:
1567 if (property->emit_store()) { 1569 if (property->emit_store()) {
1568 __ Push(Smi::FromInt(NONE)); 1570 PushOperand(Smi::FromInt(NONE));
1569 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1571 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1570 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1572 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1571 } else { 1573 } else {
1572 __ Drop(3); 1574 DropOperands(3);
1573 } 1575 }
1574 break; 1576 break;
1575 1577
1576 case ObjectLiteral::Property::PROTOTYPE: 1578 case ObjectLiteral::Property::PROTOTYPE:
1577 UNREACHABLE(); 1579 UNREACHABLE();
1578 break; 1580 break;
1579 1581
1580 case ObjectLiteral::Property::GETTER: 1582 case ObjectLiteral::Property::GETTER:
1581 __ Push(Smi::FromInt(NONE)); 1583 PushOperand(Smi::FromInt(NONE));
1582 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1584 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1583 break; 1585 break;
1584 1586
1585 case ObjectLiteral::Property::SETTER: 1587 case ObjectLiteral::Property::SETTER:
1586 __ Push(Smi::FromInt(NONE)); 1588 PushOperand(Smi::FromInt(NONE));
1587 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1589 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1588 break; 1590 break;
1589 } 1591 }
1590 } 1592 }
1591 } 1593 }
1592 1594
1593 if (expr->has_function()) { 1595 if (expr->has_function()) {
1594 DCHECK(result_saved); 1596 DCHECK(result_saved);
1595 __ LoadP(r3, MemOperand(sp)); 1597 __ LoadP(r3, MemOperand(sp));
1596 __ push(r3); 1598 __ push(r3);
1597 __ CallRuntime(Runtime::kToFastProperties); 1599 __ CallRuntime(Runtime::kToFastProperties);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 // them into the newly cloned array. 1644 // them into the newly cloned array.
1643 int array_index = 0; 1645 int array_index = 0;
1644 for (; array_index < length; array_index++) { 1646 for (; array_index < length; array_index++) {
1645 Expression* subexpr = subexprs->at(array_index); 1647 Expression* subexpr = subexprs->at(array_index);
1646 DCHECK(!subexpr->IsSpread()); 1648 DCHECK(!subexpr->IsSpread());
1647 // If the subexpression is a literal or a simple materialized literal it 1649 // If the subexpression is a literal or a simple materialized literal it
1648 // is already set in the cloned array. 1650 // is already set in the cloned array.
1649 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1651 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1650 1652
1651 if (!result_saved) { 1653 if (!result_saved) {
1652 __ push(r3); 1654 PushOperand(r3);
1653 result_saved = true; 1655 result_saved = true;
1654 } 1656 }
1655 VisitForAccumulatorValue(subexpr); 1657 VisitForAccumulatorValue(subexpr);
1656 1658
1657 __ LoadSmiLiteral(StoreDescriptor::NameRegister(), 1659 __ LoadSmiLiteral(StoreDescriptor::NameRegister(),
1658 Smi::FromInt(array_index)); 1660 Smi::FromInt(array_index));
1659 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1661 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1660 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1662 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1661 Handle<Code> ic = 1663 Handle<Code> ic =
1662 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1664 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1663 CallIC(ic); 1665 CallIC(ic);
1664 1666
1665 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1667 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1666 } 1668 }
1667 1669
1668 // In case the array literal contains spread expressions it has two parts. The 1670 // In case the array literal contains spread expressions it has two parts. The
1669 // first part is the "static" array which has a literal index is handled 1671 // first part is the "static" array which has a literal index is handled
1670 // above. The second part is the part after the first spread expression 1672 // above. The second part is the part after the first spread expression
1671 // (inclusive) and these elements gets appended to the array. Note that the 1673 // (inclusive) and these elements gets appended to the array. Note that the
1672 // number elements an iterable produces is unknown ahead of time. 1674 // number elements an iterable produces is unknown ahead of time.
1673 if (array_index < length && result_saved) { 1675 if (array_index < length && result_saved) {
1674 __ Pop(r3); 1676 PopOperand(r3);
1675 result_saved = false; 1677 result_saved = false;
1676 } 1678 }
1677 for (; array_index < length; array_index++) { 1679 for (; array_index < length; array_index++) {
1678 Expression* subexpr = subexprs->at(array_index); 1680 Expression* subexpr = subexprs->at(array_index);
1679 1681
1680 __ Push(r3); 1682 PushOperand(r3);
1681 DCHECK(!subexpr->IsSpread()); 1683 DCHECK(!subexpr->IsSpread());
1682 VisitForStackValue(subexpr); 1684 VisitForStackValue(subexpr);
1683 __ CallRuntime(Runtime::kAppendElement); 1685 CallRuntimeWithOperands(Runtime::kAppendElement);
1684 1686
1685 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1687 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1686 } 1688 }
1687 1689
1688 if (result_saved) { 1690 if (result_saved) {
1689 context()->PlugTOS(); 1691 context()->PlugTOS();
1690 } else { 1692 } else {
1691 context()->Plug(r3); 1693 context()->Plug(r3);
1692 } 1694 }
1693 } 1695 }
(...skipping 20 matching lines...) Expand all
1714 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1716 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1715 } else { 1717 } else {
1716 VisitForStackValue(property->obj()); 1718 VisitForStackValue(property->obj());
1717 } 1719 }
1718 break; 1720 break;
1719 case NAMED_SUPER_PROPERTY: 1721 case NAMED_SUPER_PROPERTY:
1720 VisitForStackValue( 1722 VisitForStackValue(
1721 property->obj()->AsSuperPropertyReference()->this_var()); 1723 property->obj()->AsSuperPropertyReference()->this_var());
1722 VisitForAccumulatorValue( 1724 VisitForAccumulatorValue(
1723 property->obj()->AsSuperPropertyReference()->home_object()); 1725 property->obj()->AsSuperPropertyReference()->home_object());
1724 __ Push(result_register()); 1726 PushOperand(result_register());
1725 if (expr->is_compound()) { 1727 if (expr->is_compound()) {
1726 const Register scratch = r4; 1728 const Register scratch = r4;
1727 __ LoadP(scratch, MemOperand(sp, kPointerSize)); 1729 __ LoadP(scratch, MemOperand(sp, kPointerSize));
1728 __ Push(scratch, result_register()); 1730 PushOperands(scratch, result_register());
1729 } 1731 }
1730 break; 1732 break;
1731 case KEYED_SUPER_PROPERTY: { 1733 case KEYED_SUPER_PROPERTY: {
1732 const Register scratch = r4; 1734 const Register scratch = r4;
1733 VisitForStackValue( 1735 VisitForStackValue(
1734 property->obj()->AsSuperPropertyReference()->this_var()); 1736 property->obj()->AsSuperPropertyReference()->this_var());
1735 VisitForAccumulatorValue( 1737 VisitForAccumulatorValue(
1736 property->obj()->AsSuperPropertyReference()->home_object()); 1738 property->obj()->AsSuperPropertyReference()->home_object());
1737 __ mr(scratch, result_register()); 1739 __ mr(scratch, result_register());
1738 VisitForAccumulatorValue(property->key()); 1740 VisitForAccumulatorValue(property->key());
1739 __ Push(scratch, result_register()); 1741 PushOperands(scratch, result_register());
1740 if (expr->is_compound()) { 1742 if (expr->is_compound()) {
1741 const Register scratch1 = r5; 1743 const Register scratch1 = r5;
1742 __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize)); 1744 __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize));
1743 __ Push(scratch1, scratch, result_register()); 1745 PushOperands(scratch1, scratch, result_register());
1744 } 1746 }
1745 break; 1747 break;
1746 } 1748 }
1747 case KEYED_PROPERTY: 1749 case KEYED_PROPERTY:
1748 if (expr->is_compound()) { 1750 if (expr->is_compound()) {
1749 VisitForStackValue(property->obj()); 1751 VisitForStackValue(property->obj());
1750 VisitForStackValue(property->key()); 1752 VisitForStackValue(property->key());
1751 __ LoadP(LoadDescriptor::ReceiverRegister(), 1753 __ LoadP(LoadDescriptor::ReceiverRegister(),
1752 MemOperand(sp, 1 * kPointerSize)); 1754 MemOperand(sp, 1 * kPointerSize));
1753 __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); 1755 __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
(...skipping 27 matching lines...) Expand all
1781 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1783 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1782 break; 1784 break;
1783 case KEYED_PROPERTY: 1785 case KEYED_PROPERTY:
1784 EmitKeyedPropertyLoad(property); 1786 EmitKeyedPropertyLoad(property);
1785 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1787 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1786 break; 1788 break;
1787 } 1789 }
1788 } 1790 }
1789 1791
1790 Token::Value op = expr->binary_op(); 1792 Token::Value op = expr->binary_op();
1791 __ push(r3); // Left operand goes on the stack. 1793 PushOperand(r3); // Left operand goes on the stack.
1792 VisitForAccumulatorValue(expr->value()); 1794 VisitForAccumulatorValue(expr->value());
1793 1795
1794 AccumulatorValueContext context(this); 1796 AccumulatorValueContext context(this);
1795 if (ShouldInlineSmiCase(op)) { 1797 if (ShouldInlineSmiCase(op)) {
1796 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(), 1798 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(),
1797 expr->value()); 1799 expr->value());
1798 } else { 1800 } else {
1799 EmitBinaryOp(expr->binary_operation(), op); 1801 EmitBinaryOp(expr->binary_operation(), op);
1800 } 1802 }
1801 1803
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 __ mr(r4, cp); 1875 __ mr(r4, cp);
1874 __ RecordWriteField(r3, JSGeneratorObject::kContextOffset, r4, r5, 1876 __ RecordWriteField(r3, JSGeneratorObject::kContextOffset, r4, r5,
1875 kLRHasBeenSaved, kDontSaveFPRegs); 1877 kLRHasBeenSaved, kDontSaveFPRegs);
1876 __ addi(r4, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1878 __ addi(r4, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1877 __ cmp(sp, r4); 1879 __ cmp(sp, r4);
1878 __ beq(&post_runtime); 1880 __ beq(&post_runtime);
1879 __ push(r3); // generator object 1881 __ push(r3); // generator object
1880 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1882 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1881 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1883 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1882 __ bind(&post_runtime); 1884 __ bind(&post_runtime);
1883 __ pop(result_register()); 1885 PopOperand(result_register());
1884 EmitReturnSequence(); 1886 EmitReturnSequence();
1885 1887
1886 __ bind(&resume); 1888 __ bind(&resume);
1887 context()->Plug(result_register()); 1889 context()->Plug(result_register());
1888 break; 1890 break;
1889 } 1891 }
1890 1892
1891 case Yield::kFinal: { 1893 case Yield::kFinal: {
1892 // Pop value from top-of-stack slot, box result into result register. 1894 // Pop value from top-of-stack slot, box result into result register.
1895 OperandStackDepthDecrement(1);
1893 EmitCreateIteratorResult(true); 1896 EmitCreateIteratorResult(true);
1894 EmitUnwindAndReturn(); 1897 EmitUnwindAndReturn();
1895 break; 1898 break;
1896 } 1899 }
1897 1900
1898 case Yield::kDelegating: 1901 case Yield::kDelegating:
1899 UNREACHABLE(); 1902 UNREACHABLE();
1900 } 1903 }
1901 } 1904 }
1902 1905
1903 1906
1904 void FullCodeGenerator::EmitGeneratorResume( 1907 void FullCodeGenerator::EmitGeneratorResume(
1905 Expression* generator, Expression* value, 1908 Expression* generator, Expression* value,
1906 JSGeneratorObject::ResumeMode resume_mode) { 1909 JSGeneratorObject::ResumeMode resume_mode) {
1907 // The value stays in r3, and is ultimately read by the resumed generator, as 1910 // The value stays in r3, and is ultimately read by the resumed generator, as
1908 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1911 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1909 // is read to throw the value when the resumed generator is already closed. 1912 // is read to throw the value when the resumed generator is already closed.
1910 // r4 will hold the generator object until the activation has been resumed. 1913 // r4 will hold the generator object until the activation has been resumed.
1911 VisitForStackValue(generator); 1914 VisitForStackValue(generator);
1912 VisitForAccumulatorValue(value); 1915 VisitForAccumulatorValue(value);
1913 __ pop(r4); 1916 PopOperand(r4);
1914 1917
1915 // Store input value into generator object. 1918 // Store input value into generator object.
1916 __ StoreP(result_register(), 1919 __ StoreP(result_register(),
1917 FieldMemOperand(r4, JSGeneratorObject::kInputOffset), r0); 1920 FieldMemOperand(r4, JSGeneratorObject::kInputOffset), r0);
1918 __ mr(r5, result_register()); 1921 __ mr(r5, result_register());
1919 __ RecordWriteField(r4, JSGeneratorObject::kInputOffset, r5, r6, 1922 __ RecordWriteField(r4, JSGeneratorObject::kInputOffset, r5, r6,
1920 kLRHasBeenSaved, kDontSaveFPRegs); 1923 kLRHasBeenSaved, kDontSaveFPRegs);
1921 1924
1922 // Load suspended function and context. 1925 // Load suspended function and context.
1923 __ LoadP(cp, FieldMemOperand(r4, JSGeneratorObject::kContextOffset)); 1926 __ LoadP(cp, FieldMemOperand(r4, JSGeneratorObject::kContextOffset));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2006 __ Push(r4, result_register()); 2009 __ Push(r4, result_register());
2007 __ Push(Smi::FromInt(resume_mode)); 2010 __ Push(Smi::FromInt(resume_mode));
2008 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 2011 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
2009 // Not reached: the runtime call returns elsewhere. 2012 // Not reached: the runtime call returns elsewhere.
2010 __ stop("not-reached"); 2013 __ stop("not-reached");
2011 2014
2012 __ bind(&done); 2015 __ bind(&done);
2013 context()->Plug(result_register()); 2016 context()->Plug(result_register());
2014 } 2017 }
2015 2018
2019 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
2020 OperandStackDepthIncrement(2);
2021 __ Push(reg1, reg2);
2022 }
2023
2024 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
2025 Register reg3) {
2026 OperandStackDepthIncrement(3);
2027 __ Push(reg1, reg2, reg3);
2028 }
2029
2030 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
2031 Register reg3, Register reg4) {
2032 OperandStackDepthIncrement(4);
2033 __ Push(reg1, reg2, reg3, reg4);
2034 }
2035
2036 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) {
2037 OperandStackDepthDecrement(2);
2038 __ Pop(reg1, reg2);
2039 }
2040
2041 void FullCodeGenerator::EmitOperandStackDepthCheck() {
2042 if (FLAG_debug_code) {
2043 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
2044 operand_stack_depth_ * kPointerSize;
2045 __ sub(r3, fp, sp);
2046 __ cmpi(r3, Operand(expected_diff));
2047 __ Assert(eq, kUnexpectedStackDepth);
2048 }
2049 }
2016 2050
2017 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2051 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2018 Label allocate, done_allocate; 2052 Label allocate, done_allocate;
2019 2053
2020 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &allocate, TAG_OBJECT); 2054 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &allocate, TAG_OBJECT);
2021 __ b(&done_allocate); 2055 __ b(&done_allocate);
2022 2056
2023 __ bind(&allocate); 2057 __ bind(&allocate);
2024 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2058 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2025 __ CallRuntime(Runtime::kAllocateInNewSpace); 2059 __ CallRuntime(Runtime::kAllocateInNewSpace);
(...skipping 29 matching lines...) Expand all
2055 Expression* left_expr, 2089 Expression* left_expr,
2056 Expression* right_expr) { 2090 Expression* right_expr) {
2057 Label done, smi_case, stub_call; 2091 Label done, smi_case, stub_call;
2058 2092
2059 Register scratch1 = r5; 2093 Register scratch1 = r5;
2060 Register scratch2 = r6; 2094 Register scratch2 = r6;
2061 2095
2062 // Get the arguments. 2096 // Get the arguments.
2063 Register left = r4; 2097 Register left = r4;
2064 Register right = r3; 2098 Register right = r3;
2065 __ pop(left); 2099 PopOperand(left);
2066 2100
2067 // Perform combined smi check on both operands. 2101 // Perform combined smi check on both operands.
2068 __ orx(scratch1, left, right); 2102 __ orx(scratch1, left, right);
2069 STATIC_ASSERT(kSmiTag == 0); 2103 STATIC_ASSERT(kSmiTag == 0);
2070 JumpPatchSite patch_site(masm_); 2104 JumpPatchSite patch_site(masm_);
2071 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2105 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2072 2106
2073 __ bind(&stub_call); 2107 __ bind(&stub_call);
2074 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2108 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2075 CallIC(code, expr->BinaryOperationFeedbackId()); 2109 CallIC(code, expr->BinaryOperationFeedbackId());
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2179 for (int i = 0; i < lit->properties()->length(); i++) { 2213 for (int i = 0; i < lit->properties()->length(); i++) {
2180 ObjectLiteral::Property* property = lit->properties()->at(i); 2214 ObjectLiteral::Property* property = lit->properties()->at(i);
2181 Expression* value = property->value(); 2215 Expression* value = property->value();
2182 2216
2183 Register scratch = r4; 2217 Register scratch = r4;
2184 if (property->is_static()) { 2218 if (property->is_static()) {
2185 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor 2219 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor
2186 } else { 2220 } else {
2187 __ LoadP(scratch, MemOperand(sp, 0)); // prototype 2221 __ LoadP(scratch, MemOperand(sp, 0)); // prototype
2188 } 2222 }
2189 __ push(scratch); 2223 PushOperand(scratch);
2190 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2224 EmitPropertyKey(property, lit->GetIdForProperty(i));
2191 2225
2192 // The static prototype property is read only. We handle the non computed 2226 // The static prototype property is read only. We handle the non computed
2193 // property name case in the parser. Since this is the only case where we 2227 // property name case in the parser. Since this is the only case where we
2194 // need to check for an own read only property we special case this so we do 2228 // need to check for an own read only property we special case this so we do
2195 // not need to do this for every property. 2229 // not need to do this for every property.
2196 if (property->is_static() && property->is_computed_name()) { 2230 if (property->is_static() && property->is_computed_name()) {
2197 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2231 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2198 __ push(r3); 2232 __ push(r3);
2199 } 2233 }
2200 2234
2201 VisitForStackValue(value); 2235 VisitForStackValue(value);
2202 if (NeedsHomeObject(value)) { 2236 if (NeedsHomeObject(value)) {
2203 EmitSetHomeObject(value, 2, property->GetSlot()); 2237 EmitSetHomeObject(value, 2, property->GetSlot());
2204 } 2238 }
2205 2239
2206 switch (property->kind()) { 2240 switch (property->kind()) {
2207 case ObjectLiteral::Property::CONSTANT: 2241 case ObjectLiteral::Property::CONSTANT:
2208 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2242 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2209 case ObjectLiteral::Property::PROTOTYPE: 2243 case ObjectLiteral::Property::PROTOTYPE:
2210 UNREACHABLE(); 2244 UNREACHABLE();
2211 case ObjectLiteral::Property::COMPUTED: 2245 case ObjectLiteral::Property::COMPUTED:
2212 __ Push(Smi::FromInt(DONT_ENUM)); 2246 PushOperand(Smi::FromInt(DONT_ENUM));
2213 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2247 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2214 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2248 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2215 break; 2249 break;
2216 2250
2217 case ObjectLiteral::Property::GETTER: 2251 case ObjectLiteral::Property::GETTER:
2218 __ Push(Smi::FromInt(DONT_ENUM)); 2252 PushOperand(Smi::FromInt(DONT_ENUM));
2219 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2253 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2220 break; 2254 break;
2221 2255
2222 case ObjectLiteral::Property::SETTER: 2256 case ObjectLiteral::Property::SETTER:
2223 __ Push(Smi::FromInt(DONT_ENUM)); 2257 PushOperand(Smi::FromInt(DONT_ENUM));
2224 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2258 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2225 break; 2259 break;
2226 2260
2227 default: 2261 default:
2228 UNREACHABLE(); 2262 UNREACHABLE();
2229 } 2263 }
2230 } 2264 }
2231 } 2265 }
2232 2266
2233 2267
2234 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2268 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2235 __ pop(r4); 2269 PopOperand(r4);
2236 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2270 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2237 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2271 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2238 CallIC(code, expr->BinaryOperationFeedbackId()); 2272 CallIC(code, expr->BinaryOperationFeedbackId());
2239 patch_site.EmitPatchInfo(); 2273 patch_site.EmitPatchInfo();
2240 context()->Plug(r3); 2274 context()->Plug(r3);
2241 } 2275 }
2242 2276
2243 2277
2244 void FullCodeGenerator::EmitAssignment(Expression* expr, 2278 void FullCodeGenerator::EmitAssignment(Expression* expr,
2245 FeedbackVectorSlot slot) { 2279 FeedbackVectorSlot slot) {
2246 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2280 DCHECK(expr->IsValidReferenceExpressionOrThis());
2247 2281
2248 Property* prop = expr->AsProperty(); 2282 Property* prop = expr->AsProperty();
2249 LhsKind assign_type = Property::GetAssignType(prop); 2283 LhsKind assign_type = Property::GetAssignType(prop);
2250 2284
2251 switch (assign_type) { 2285 switch (assign_type) {
2252 case VARIABLE: { 2286 case VARIABLE: {
2253 Variable* var = expr->AsVariableProxy()->var(); 2287 Variable* var = expr->AsVariableProxy()->var();
2254 EffectContext context(this); 2288 EffectContext context(this);
2255 EmitVariableAssignment(var, Token::ASSIGN, slot); 2289 EmitVariableAssignment(var, Token::ASSIGN, slot);
2256 break; 2290 break;
2257 } 2291 }
2258 case NAMED_PROPERTY: { 2292 case NAMED_PROPERTY: {
2259 __ push(r3); // Preserve value. 2293 PushOperand(r3); // Preserve value.
2260 VisitForAccumulatorValue(prop->obj()); 2294 VisitForAccumulatorValue(prop->obj());
2261 __ Move(StoreDescriptor::ReceiverRegister(), r3); 2295 __ Move(StoreDescriptor::ReceiverRegister(), r3);
2262 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2296 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2263 __ mov(StoreDescriptor::NameRegister(), 2297 __ mov(StoreDescriptor::NameRegister(),
2264 Operand(prop->key()->AsLiteral()->value())); 2298 Operand(prop->key()->AsLiteral()->value()));
2265 EmitLoadStoreICSlot(slot); 2299 EmitLoadStoreICSlot(slot);
2266 CallStoreIC(); 2300 CallStoreIC();
2267 break; 2301 break;
2268 } 2302 }
2269 case NAMED_SUPER_PROPERTY: { 2303 case NAMED_SUPER_PROPERTY: {
2270 __ Push(r3); 2304 PushOperand(r3);
2271 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2305 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2272 VisitForAccumulatorValue( 2306 VisitForAccumulatorValue(
2273 prop->obj()->AsSuperPropertyReference()->home_object()); 2307 prop->obj()->AsSuperPropertyReference()->home_object());
2274 // stack: value, this; r3: home_object 2308 // stack: value, this; r3: home_object
2275 Register scratch = r5; 2309 Register scratch = r5;
2276 Register scratch2 = r6; 2310 Register scratch2 = r6;
2277 __ mr(scratch, result_register()); // home_object 2311 __ mr(scratch, result_register()); // home_object
2278 __ LoadP(r3, MemOperand(sp, kPointerSize)); // value 2312 __ LoadP(r3, MemOperand(sp, kPointerSize)); // value
2279 __ LoadP(scratch2, MemOperand(sp, 0)); // this 2313 __ LoadP(scratch2, MemOperand(sp, 0)); // this
2280 __ StoreP(scratch2, MemOperand(sp, kPointerSize)); // this 2314 __ StoreP(scratch2, MemOperand(sp, kPointerSize)); // this
2281 __ StoreP(scratch, MemOperand(sp, 0)); // home_object 2315 __ StoreP(scratch, MemOperand(sp, 0)); // home_object
2282 // stack: this, home_object; r3: value 2316 // stack: this, home_object; r3: value
2283 EmitNamedSuperPropertyStore(prop); 2317 EmitNamedSuperPropertyStore(prop);
2284 break; 2318 break;
2285 } 2319 }
2286 case KEYED_SUPER_PROPERTY: { 2320 case KEYED_SUPER_PROPERTY: {
2287 __ Push(r3); 2321 PushOperand(r3);
2288 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2322 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2289 VisitForStackValue( 2323 VisitForStackValue(
2290 prop->obj()->AsSuperPropertyReference()->home_object()); 2324 prop->obj()->AsSuperPropertyReference()->home_object());
2291 VisitForAccumulatorValue(prop->key()); 2325 VisitForAccumulatorValue(prop->key());
2292 Register scratch = r5; 2326 Register scratch = r5;
2293 Register scratch2 = r6; 2327 Register scratch2 = r6;
2294 __ LoadP(scratch2, MemOperand(sp, 2 * kPointerSize)); // value 2328 __ LoadP(scratch2, MemOperand(sp, 2 * kPointerSize)); // value
2295 // stack: value, this, home_object; r3: key, r6: value 2329 // stack: value, this, home_object; r3: key, r6: value
2296 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // this 2330 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // this
2297 __ StoreP(scratch, MemOperand(sp, 2 * kPointerSize)); 2331 __ StoreP(scratch, MemOperand(sp, 2 * kPointerSize));
2298 __ LoadP(scratch, MemOperand(sp, 0)); // home_object 2332 __ LoadP(scratch, MemOperand(sp, 0)); // home_object
2299 __ StoreP(scratch, MemOperand(sp, kPointerSize)); 2333 __ StoreP(scratch, MemOperand(sp, kPointerSize));
2300 __ StoreP(r3, MemOperand(sp, 0)); 2334 __ StoreP(r3, MemOperand(sp, 0));
2301 __ Move(r3, scratch2); 2335 __ Move(r3, scratch2);
2302 // stack: this, home_object, key; r3: value. 2336 // stack: this, home_object, key; r3: value.
2303 EmitKeyedSuperPropertyStore(prop); 2337 EmitKeyedSuperPropertyStore(prop);
2304 break; 2338 break;
2305 } 2339 }
2306 case KEYED_PROPERTY: { 2340 case KEYED_PROPERTY: {
2307 __ push(r3); // Preserve value. 2341 PushOperand(r3); // Preserve value.
2308 VisitForStackValue(prop->obj()); 2342 VisitForStackValue(prop->obj());
2309 VisitForAccumulatorValue(prop->key()); 2343 VisitForAccumulatorValue(prop->key());
2310 __ Move(StoreDescriptor::NameRegister(), r3); 2344 __ Move(StoreDescriptor::NameRegister(), r3);
2311 __ Pop(StoreDescriptor::ValueRegister(), 2345 PopOperands(StoreDescriptor::ValueRegister(),
2312 StoreDescriptor::ReceiverRegister()); 2346 StoreDescriptor::ReceiverRegister());
2313 EmitLoadStoreICSlot(slot); 2347 EmitLoadStoreICSlot(slot);
2314 Handle<Code> ic = 2348 Handle<Code> ic =
2315 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2349 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2316 CallIC(ic); 2350 CallIC(ic);
2317 break; 2351 break;
2318 } 2352 }
2319 } 2353 }
2320 context()->Plug(r3); 2354 context()->Plug(r3);
2321 } 2355 }
2322 2356
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2440 2474
2441 2475
2442 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2476 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2443 // Assignment to a property, using a named store IC. 2477 // Assignment to a property, using a named store IC.
2444 Property* prop = expr->target()->AsProperty(); 2478 Property* prop = expr->target()->AsProperty();
2445 DCHECK(prop != NULL); 2479 DCHECK(prop != NULL);
2446 DCHECK(prop->key()->IsLiteral()); 2480 DCHECK(prop->key()->IsLiteral());
2447 2481
2448 __ mov(StoreDescriptor::NameRegister(), 2482 __ mov(StoreDescriptor::NameRegister(),
2449 Operand(prop->key()->AsLiteral()->value())); 2483 Operand(prop->key()->AsLiteral()->value()));
2450 __ pop(StoreDescriptor::ReceiverRegister()); 2484 PopOperand(StoreDescriptor::ReceiverRegister());
2451 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2485 EmitLoadStoreICSlot(expr->AssignmentSlot());
2452 CallStoreIC(); 2486 CallStoreIC();
2453 2487
2454 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2488 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2455 context()->Plug(r3); 2489 context()->Plug(r3);
2456 } 2490 }
2457 2491
2458 2492
2459 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2493 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2460 // Assignment to named property of super. 2494 // Assignment to named property of super.
2461 // r3 : value 2495 // r3 : value
2462 // stack : receiver ('this'), home_object 2496 // stack : receiver ('this'), home_object
2463 DCHECK(prop != NULL); 2497 DCHECK(prop != NULL);
2464 Literal* key = prop->key()->AsLiteral(); 2498 Literal* key = prop->key()->AsLiteral();
2465 DCHECK(key != NULL); 2499 DCHECK(key != NULL);
2466 2500
2467 __ Push(key->value()); 2501 PushOperand(key->value());
2468 __ Push(r3); 2502 PushOperand(r3);
2469 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2503 CallRuntimeWithOperands((is_strict(language_mode())
2470 : Runtime::kStoreToSuper_Sloppy)); 2504 ? Runtime::kStoreToSuper_Strict
2505 : Runtime::kStoreToSuper_Sloppy));
2471 } 2506 }
2472 2507
2473 2508
2474 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2509 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2475 // Assignment to named property of super. 2510 // Assignment to named property of super.
2476 // r3 : value 2511 // r3 : value
2477 // stack : receiver ('this'), home_object, key 2512 // stack : receiver ('this'), home_object, key
2478 DCHECK(prop != NULL); 2513 DCHECK(prop != NULL);
2479 2514
2480 __ Push(r3); 2515 PushOperand(r3);
2481 __ CallRuntime((is_strict(language_mode()) 2516 CallRuntimeWithOperands((is_strict(language_mode())
2482 ? Runtime::kStoreKeyedToSuper_Strict 2517 ? Runtime::kStoreKeyedToSuper_Strict
2483 : Runtime::kStoreKeyedToSuper_Sloppy)); 2518 : Runtime::kStoreKeyedToSuper_Sloppy));
2484 } 2519 }
2485 2520
2486 2521
2487 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2522 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2488 // Assignment to a property, using a keyed store IC. 2523 // Assignment to a property, using a keyed store IC.
2489 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2524 PopOperands(StoreDescriptor::ReceiverRegister(),
2525 StoreDescriptor::NameRegister());
2490 DCHECK(StoreDescriptor::ValueRegister().is(r3)); 2526 DCHECK(StoreDescriptor::ValueRegister().is(r3));
2491 2527
2492 Handle<Code> ic = 2528 Handle<Code> ic =
2493 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2529 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2494 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2530 EmitLoadStoreICSlot(expr->AssignmentSlot());
2495 CallIC(ic); 2531 CallIC(ic);
2496 2532
2497 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2533 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2498 context()->Plug(r3); 2534 context()->Plug(r3);
2499 } 2535 }
(...skipping 14 matching lines...) Expand all
2514 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2550 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2515 VisitForStackValue( 2551 VisitForStackValue(
2516 expr->obj()->AsSuperPropertyReference()->home_object()); 2552 expr->obj()->AsSuperPropertyReference()->home_object());
2517 EmitNamedSuperPropertyLoad(expr); 2553 EmitNamedSuperPropertyLoad(expr);
2518 } 2554 }
2519 } else { 2555 } else {
2520 if (!expr->IsSuperAccess()) { 2556 if (!expr->IsSuperAccess()) {
2521 VisitForStackValue(expr->obj()); 2557 VisitForStackValue(expr->obj());
2522 VisitForAccumulatorValue(expr->key()); 2558 VisitForAccumulatorValue(expr->key());
2523 __ Move(LoadDescriptor::NameRegister(), r3); 2559 __ Move(LoadDescriptor::NameRegister(), r3);
2524 __ pop(LoadDescriptor::ReceiverRegister()); 2560 PopOperand(LoadDescriptor::ReceiverRegister());
2525 EmitKeyedPropertyLoad(expr); 2561 EmitKeyedPropertyLoad(expr);
2526 } else { 2562 } else {
2527 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2563 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2528 VisitForStackValue( 2564 VisitForStackValue(
2529 expr->obj()->AsSuperPropertyReference()->home_object()); 2565 expr->obj()->AsSuperPropertyReference()->home_object());
2530 VisitForStackValue(expr->key()); 2566 VisitForStackValue(expr->key());
2531 EmitKeyedSuperPropertyLoad(expr); 2567 EmitKeyedSuperPropertyLoad(expr);
2532 } 2568 }
2533 } 2569 }
2534 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2570 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
(...skipping 15 matching lines...) Expand all
2550 ConvertReceiverMode convert_mode; 2586 ConvertReceiverMode convert_mode;
2551 if (callee->IsVariableProxy()) { 2587 if (callee->IsVariableProxy()) {
2552 { 2588 {
2553 StackValueContext context(this); 2589 StackValueContext context(this);
2554 EmitVariableLoad(callee->AsVariableProxy()); 2590 EmitVariableLoad(callee->AsVariableProxy());
2555 PrepareForBailout(callee, NO_REGISTERS); 2591 PrepareForBailout(callee, NO_REGISTERS);
2556 } 2592 }
2557 // Push undefined as receiver. This is patched in the method prologue if it 2593 // Push undefined as receiver. This is patched in the method prologue if it
2558 // is a sloppy mode method. 2594 // is a sloppy mode method.
2559 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 2595 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2560 __ push(r0); 2596 PushOperand(r0);
2561 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2597 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2562 } else { 2598 } else {
2563 // Load the function from the receiver. 2599 // Load the function from the receiver.
2564 DCHECK(callee->IsProperty()); 2600 DCHECK(callee->IsProperty());
2565 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2601 DCHECK(!callee->AsProperty()->IsSuperAccess());
2566 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2602 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2567 EmitNamedPropertyLoad(callee->AsProperty()); 2603 EmitNamedPropertyLoad(callee->AsProperty());
2568 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2604 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2569 // Push the target function under the receiver. 2605 // Push the target function under the receiver.
2570 __ LoadP(r0, MemOperand(sp, 0)); 2606 __ LoadP(r0, MemOperand(sp, 0));
2571 __ push(r0); 2607 PushOperand(r0);
2572 __ StoreP(r3, MemOperand(sp, kPointerSize)); 2608 __ StoreP(r3, MemOperand(sp, kPointerSize));
2573 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2609 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2574 } 2610 }
2575 2611
2576 EmitCall(expr, convert_mode); 2612 EmitCall(expr, convert_mode);
2577 } 2613 }
2578 2614
2579 2615
2580 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2616 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2581 Expression* callee = expr->expression(); 2617 Expression* callee = expr->expression();
2582 DCHECK(callee->IsProperty()); 2618 DCHECK(callee->IsProperty());
2583 Property* prop = callee->AsProperty(); 2619 Property* prop = callee->AsProperty();
2584 DCHECK(prop->IsSuperAccess()); 2620 DCHECK(prop->IsSuperAccess());
2585 SetExpressionPosition(prop); 2621 SetExpressionPosition(prop);
2586 2622
2587 Literal* key = prop->key()->AsLiteral(); 2623 Literal* key = prop->key()->AsLiteral();
2588 DCHECK(!key->value()->IsSmi()); 2624 DCHECK(!key->value()->IsSmi());
2589 // Load the function from the receiver. 2625 // Load the function from the receiver.
2590 const Register scratch = r4; 2626 const Register scratch = r4;
2591 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2627 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2592 VisitForAccumulatorValue(super_ref->home_object()); 2628 VisitForAccumulatorValue(super_ref->home_object());
2593 __ mr(scratch, r3); 2629 __ mr(scratch, r3);
2594 VisitForAccumulatorValue(super_ref->this_var()); 2630 VisitForAccumulatorValue(super_ref->this_var());
2595 __ Push(scratch, r3, r3, scratch); 2631 PushOperands(scratch, r3, r3, scratch);
2596 __ Push(key->value()); 2632 PushOperand(key->value());
2597 2633
2598 // Stack here: 2634 // Stack here:
2599 // - home_object 2635 // - home_object
2600 // - this (receiver) 2636 // - this (receiver)
2601 // - this (receiver) <-- LoadFromSuper will pop here and below. 2637 // - this (receiver) <-- LoadFromSuper will pop here and below.
2602 // - home_object 2638 // - home_object
2603 // - key 2639 // - key
2604 __ CallRuntime(Runtime::kLoadFromSuper); 2640 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2605 2641
2606 // Replace home_object with target function. 2642 // Replace home_object with target function.
2607 __ StoreP(r3, MemOperand(sp, kPointerSize)); 2643 __ StoreP(r3, MemOperand(sp, kPointerSize));
2608 2644
2609 // Stack here: 2645 // Stack here:
2610 // - target function 2646 // - target function
2611 // - this (receiver) 2647 // - this (receiver)
2612 EmitCall(expr); 2648 EmitCall(expr);
2613 } 2649 }
2614 2650
2615 2651
2616 // Code common for calls using the IC. 2652 // Code common for calls using the IC.
2617 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { 2653 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) {
2618 // Load the key. 2654 // Load the key.
2619 VisitForAccumulatorValue(key); 2655 VisitForAccumulatorValue(key);
2620 2656
2621 Expression* callee = expr->expression(); 2657 Expression* callee = expr->expression();
2622 2658
2623 // Load the function from the receiver. 2659 // Load the function from the receiver.
2624 DCHECK(callee->IsProperty()); 2660 DCHECK(callee->IsProperty());
2625 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2661 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2626 __ Move(LoadDescriptor::NameRegister(), r3); 2662 __ Move(LoadDescriptor::NameRegister(), r3);
2627 EmitKeyedPropertyLoad(callee->AsProperty()); 2663 EmitKeyedPropertyLoad(callee->AsProperty());
2628 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2664 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2629 2665
2630 // Push the target function under the receiver. 2666 // Push the target function under the receiver.
2631 __ LoadP(ip, MemOperand(sp, 0)); 2667 __ LoadP(ip, MemOperand(sp, 0));
2632 __ push(ip); 2668 PushOperand(ip);
2633 __ StoreP(r3, MemOperand(sp, kPointerSize)); 2669 __ StoreP(r3, MemOperand(sp, kPointerSize));
2634 2670
2635 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2671 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2636 } 2672 }
2637 2673
2638 2674
2639 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2675 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2640 Expression* callee = expr->expression(); 2676 Expression* callee = expr->expression();
2641 DCHECK(callee->IsProperty()); 2677 DCHECK(callee->IsProperty());
2642 Property* prop = callee->AsProperty(); 2678 Property* prop = callee->AsProperty();
2643 DCHECK(prop->IsSuperAccess()); 2679 DCHECK(prop->IsSuperAccess());
2644 2680
2645 SetExpressionPosition(prop); 2681 SetExpressionPosition(prop);
2646 // Load the function from the receiver. 2682 // Load the function from the receiver.
2647 const Register scratch = r4; 2683 const Register scratch = r4;
2648 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2684 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2649 VisitForAccumulatorValue(super_ref->home_object()); 2685 VisitForAccumulatorValue(super_ref->home_object());
2650 __ mr(scratch, r3); 2686 __ mr(scratch, r3);
2651 VisitForAccumulatorValue(super_ref->this_var()); 2687 VisitForAccumulatorValue(super_ref->this_var());
2652 __ Push(scratch, r3, r3, scratch); 2688 PushOperands(scratch, r3, r3, scratch);
2653 VisitForStackValue(prop->key()); 2689 VisitForStackValue(prop->key());
2654 2690
2655 // Stack here: 2691 // Stack here:
2656 // - home_object 2692 // - home_object
2657 // - this (receiver) 2693 // - this (receiver)
2658 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2694 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2659 // - home_object 2695 // - home_object
2660 // - key 2696 // - key
2661 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2697 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2662 2698
2663 // Replace home_object with target function. 2699 // Replace home_object with target function.
2664 __ StoreP(r3, MemOperand(sp, kPointerSize)); 2700 __ StoreP(r3, MemOperand(sp, kPointerSize));
2665 2701
2666 // Stack here: 2702 // Stack here:
2667 // - target function 2703 // - target function
2668 // - this (receiver) 2704 // - this (receiver)
2669 EmitCall(expr); 2705 EmitCall(expr);
2670 } 2706 }
2671 2707
(...skipping 17 matching lines...) Expand all
2689 EmitProfilingCounterHandlingForReturnSequence(true); 2725 EmitProfilingCounterHandlingForReturnSequence(true);
2690 } 2726 }
2691 Handle<Code> ic = 2727 Handle<Code> ic =
2692 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2728 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2693 .code(); 2729 .code();
2694 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot())); 2730 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot()));
2695 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 2731 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2696 // Don't assign a type feedback id to the IC, since type feedback is provided 2732 // Don't assign a type feedback id to the IC, since type feedback is provided
2697 // by the vector above. 2733 // by the vector above.
2698 CallIC(ic); 2734 CallIC(ic);
2735 OperandStackDepthDecrement(arg_count + 1);
2699 2736
2700 RecordJSReturnSite(expr); 2737 RecordJSReturnSite(expr);
2701 // Restore context register. 2738 // Restore context register.
2702 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2739 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2703 context()->DropAndPlug(1, r3); 2740 context()->DropAndPlug(1, r3);
2704 } 2741 }
2705 2742
2706 2743
2707 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2744 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2708 // r7: copy of the first argument or undefined if it doesn't exist. 2745 // r7: copy of the first argument or undefined if it doesn't exist.
(...skipping 26 matching lines...) Expand all
2735 SetExpressionPosition(callee); 2772 SetExpressionPosition(callee);
2736 // Generate code for loading from variables potentially shadowed by 2773 // Generate code for loading from variables potentially shadowed by
2737 // eval-introduced variables. 2774 // eval-introduced variables.
2738 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2775 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2739 2776
2740 __ bind(&slow); 2777 __ bind(&slow);
2741 // Call the runtime to find the function to call (returned in r3) and 2778 // Call the runtime to find the function to call (returned in r3) and
2742 // the object holding it (returned in r4). 2779 // the object holding it (returned in r4).
2743 __ Push(callee->name()); 2780 __ Push(callee->name());
2744 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2781 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2745 __ Push(r3, r4); // Function, receiver. 2782 PushOperands(r3, r4); // Function, receiver.
2746 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2783 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2747 2784
2748 // If fast case code has been generated, emit code to push the function 2785 // If fast case code has been generated, emit code to push the function
2749 // and receiver and have the slow path jump around this code. 2786 // and receiver and have the slow path jump around this code.
2750 if (done.is_linked()) { 2787 if (done.is_linked()) {
2751 Label call; 2788 Label call;
2752 __ b(&call); 2789 __ b(&call);
2753 __ bind(&done); 2790 __ bind(&done);
2754 // Push function. 2791 // Push function.
2755 __ push(r3); 2792 __ push(r3);
2756 // Pass undefined as the receiver, which is the WithBaseObject of a 2793 // Pass undefined as the receiver, which is the WithBaseObject of a
2757 // non-object environment record. If the callee is sloppy, it will patch 2794 // non-object environment record. If the callee is sloppy, it will patch
2758 // it up to be the global receiver. 2795 // it up to be the global receiver.
2759 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); 2796 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
2760 __ push(r4); 2797 __ push(r4);
2761 __ bind(&call); 2798 __ bind(&call);
2762 } 2799 }
2763 } else { 2800 } else {
2764 VisitForStackValue(callee); 2801 VisitForStackValue(callee);
2765 // refEnv.WithBaseObject() 2802 // refEnv.WithBaseObject()
2766 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); 2803 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
2767 __ push(r5); // Reserved receiver slot. 2804 PushOperand(r5); // Reserved receiver slot.
2768 } 2805 }
2769 } 2806 }
2770 2807
2771 2808
2772 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2809 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2773 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2810 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2774 // to resolve the function we need to call. Then we call the resolved 2811 // to resolve the function we need to call. Then we call the resolved
2775 // function using the given arguments. 2812 // function using the given arguments.
2776 ZoneList<Expression*>* args = expr->arguments(); 2813 ZoneList<Expression*>* args = expr->arguments();
2777 int arg_count = args->length(); 2814 int arg_count = args->length();
(...skipping 16 matching lines...) Expand all
2794 2831
2795 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2832 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2796 2833
2797 // Record source position for debugger. 2834 // Record source position for debugger.
2798 SetCallPosition(expr); 2835 SetCallPosition(expr);
2799 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 2836 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2800 __ mov(r3, Operand(arg_count)); 2837 __ mov(r3, Operand(arg_count));
2801 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2838 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2802 expr->tail_call_mode()), 2839 expr->tail_call_mode()),
2803 RelocInfo::CODE_TARGET); 2840 RelocInfo::CODE_TARGET);
2841 OperandStackDepthDecrement(arg_count + 1);
2804 RecordJSReturnSite(expr); 2842 RecordJSReturnSite(expr);
2805 // Restore context register. 2843 // Restore context register.
2806 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2844 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2807 context()->DropAndPlug(1, r3); 2845 context()->DropAndPlug(1, r3);
2808 } 2846 }
2809 2847
2810 2848
2811 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2849 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2812 Comment cmnt(masm_, "[ CallNew"); 2850 Comment cmnt(masm_, "[ CallNew");
2813 // According to ECMA-262, section 11.2.2, page 44, the function 2851 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2834 // Load function and argument count into r4 and r3. 2872 // Load function and argument count into r4 and r3.
2835 __ mov(r3, Operand(arg_count)); 2873 __ mov(r3, Operand(arg_count));
2836 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); 2874 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0);
2837 2875
2838 // Record call targets in unoptimized code. 2876 // Record call targets in unoptimized code.
2839 __ EmitLoadTypeFeedbackVector(r5); 2877 __ EmitLoadTypeFeedbackVector(r5);
2840 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot())); 2878 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot()));
2841 2879
2842 CallConstructStub stub(isolate()); 2880 CallConstructStub stub(isolate());
2843 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2881 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2882 OperandStackDepthDecrement(arg_count + 1);
2844 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2883 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2845 // Restore context register. 2884 // Restore context register.
2846 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2885 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2847 context()->Plug(r3); 2886 context()->Plug(r3);
2848 } 2887 }
2849 2888
2850 2889
2851 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2890 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2852 SuperCallReference* super_call_ref = 2891 SuperCallReference* super_call_ref =
2853 expr->expression()->AsSuperCallReference(); 2892 expr->expression()->AsSuperCallReference();
2854 DCHECK_NOT_NULL(super_call_ref); 2893 DCHECK_NOT_NULL(super_call_ref);
2855 2894
2856 // Push the super constructor target on the stack (may be null, 2895 // Push the super constructor target on the stack (may be null,
2857 // but the Construct builtin can deal with that properly). 2896 // but the Construct builtin can deal with that properly).
2858 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2897 VisitForAccumulatorValue(super_call_ref->this_function_var());
2859 __ AssertFunction(result_register()); 2898 __ AssertFunction(result_register());
2860 __ LoadP(result_register(), 2899 __ LoadP(result_register(),
2861 FieldMemOperand(result_register(), HeapObject::kMapOffset)); 2900 FieldMemOperand(result_register(), HeapObject::kMapOffset));
2862 __ LoadP(result_register(), 2901 __ LoadP(result_register(),
2863 FieldMemOperand(result_register(), Map::kPrototypeOffset)); 2902 FieldMemOperand(result_register(), Map::kPrototypeOffset));
2864 __ Push(result_register()); 2903 PushOperand(result_register());
2865 2904
2866 // Push the arguments ("left-to-right") on the stack. 2905 // Push the arguments ("left-to-right") on the stack.
2867 ZoneList<Expression*>* args = expr->arguments(); 2906 ZoneList<Expression*>* args = expr->arguments();
2868 int arg_count = args->length(); 2907 int arg_count = args->length();
2869 for (int i = 0; i < arg_count; i++) { 2908 for (int i = 0; i < arg_count; i++) {
2870 VisitForStackValue(args->at(i)); 2909 VisitForStackValue(args->at(i));
2871 } 2910 }
2872 2911
2873 // Call the construct call builtin that handles allocation and 2912 // Call the construct call builtin that handles allocation and
2874 // constructor invocation. 2913 // constructor invocation.
2875 SetConstructCallPosition(expr); 2914 SetConstructCallPosition(expr);
2876 2915
2877 // Load new target into r6. 2916 // Load new target into r6.
2878 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2917 VisitForAccumulatorValue(super_call_ref->new_target_var());
2879 __ mr(r6, result_register()); 2918 __ mr(r6, result_register());
2880 2919
2881 // Load function and argument count into r1 and r0. 2920 // Load function and argument count into r1 and r0.
2882 __ mov(r3, Operand(arg_count)); 2921 __ mov(r3, Operand(arg_count));
2883 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); 2922 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize));
2884 2923
2885 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2924 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2925 OperandStackDepthDecrement(arg_count + 1);
2886 2926
2887 RecordJSReturnSite(expr); 2927 RecordJSReturnSite(expr);
2888 2928
2889 // Restore context register. 2929 // Restore context register.
2890 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2930 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2891 context()->Plug(r3); 2931 context()->Plug(r3);
2892 } 2932 }
2893 2933
2894 2934
2895 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2935 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
3097 ZoneList<Expression*>* args = expr->arguments(); 3137 ZoneList<Expression*>* args = expr->arguments();
3098 DCHECK_EQ(3, args->length()); 3138 DCHECK_EQ(3, args->length());
3099 3139
3100 Register string = r3; 3140 Register string = r3;
3101 Register index = r4; 3141 Register index = r4;
3102 Register value = r5; 3142 Register value = r5;
3103 3143
3104 VisitForStackValue(args->at(0)); // index 3144 VisitForStackValue(args->at(0)); // index
3105 VisitForStackValue(args->at(1)); // value 3145 VisitForStackValue(args->at(1)); // value
3106 VisitForAccumulatorValue(args->at(2)); // string 3146 VisitForAccumulatorValue(args->at(2)); // string
3107 __ Pop(index, value); 3147 PopOperands(index, value);
3108 3148
3109 if (FLAG_debug_code) { 3149 if (FLAG_debug_code) {
3110 __ TestIfSmi(value, r0); 3150 __ TestIfSmi(value, r0);
3111 __ Check(eq, kNonSmiValue, cr0); 3151 __ Check(eq, kNonSmiValue, cr0);
3112 __ TestIfSmi(index, r0); 3152 __ TestIfSmi(index, r0);
3113 __ Check(eq, kNonSmiIndex, cr0); 3153 __ Check(eq, kNonSmiIndex, cr0);
3114 __ SmiUntag(index, index); 3154 __ SmiUntag(index, index);
3115 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3155 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3116 __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); 3156 __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
3117 __ SmiTag(index, index); 3157 __ SmiTag(index, index);
(...skipping 11 matching lines...) Expand all
3129 ZoneList<Expression*>* args = expr->arguments(); 3169 ZoneList<Expression*>* args = expr->arguments();
3130 DCHECK_EQ(3, args->length()); 3170 DCHECK_EQ(3, args->length());
3131 3171
3132 Register string = r3; 3172 Register string = r3;
3133 Register index = r4; 3173 Register index = r4;
3134 Register value = r5; 3174 Register value = r5;
3135 3175
3136 VisitForStackValue(args->at(0)); // index 3176 VisitForStackValue(args->at(0)); // index
3137 VisitForStackValue(args->at(1)); // value 3177 VisitForStackValue(args->at(1)); // value
3138 VisitForAccumulatorValue(args->at(2)); // string 3178 VisitForAccumulatorValue(args->at(2)); // string
3139 __ Pop(index, value); 3179 PopOperands(index, value);
3140 3180
3141 if (FLAG_debug_code) { 3181 if (FLAG_debug_code) {
3142 __ TestIfSmi(value, r0); 3182 __ TestIfSmi(value, r0);
3143 __ Check(eq, kNonSmiValue, cr0); 3183 __ Check(eq, kNonSmiValue, cr0);
3144 __ TestIfSmi(index, r0); 3184 __ TestIfSmi(index, r0);
3145 __ Check(eq, kNonSmiIndex, cr0); 3185 __ Check(eq, kNonSmiIndex, cr0);
3146 __ SmiUntag(index, index); 3186 __ SmiUntag(index, index);
3147 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3187 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3148 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3188 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3149 __ SmiTag(index, index); 3189 __ SmiTag(index, index);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3195 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { 3235 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
3196 ZoneList<Expression*>* args = expr->arguments(); 3236 ZoneList<Expression*>* args = expr->arguments();
3197 DCHECK(args->length() == 2); 3237 DCHECK(args->length() == 2);
3198 VisitForStackValue(args->at(0)); 3238 VisitForStackValue(args->at(0));
3199 VisitForAccumulatorValue(args->at(1)); 3239 VisitForAccumulatorValue(args->at(1));
3200 3240
3201 Register object = r4; 3241 Register object = r4;
3202 Register index = r3; 3242 Register index = r3;
3203 Register result = r6; 3243 Register result = r6;
3204 3244
3205 __ pop(object); 3245 PopOperand(object);
3206 3246
3207 Label need_conversion; 3247 Label need_conversion;
3208 Label index_out_of_range; 3248 Label index_out_of_range;
3209 Label done; 3249 Label done;
3210 StringCharCodeAtGenerator generator(object, index, result, &need_conversion, 3250 StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
3211 &need_conversion, &index_out_of_range, 3251 &need_conversion, &index_out_of_range,
3212 STRING_INDEX_IS_NUMBER); 3252 STRING_INDEX_IS_NUMBER);
3213 generator.GenerateFast(masm_); 3253 generator.GenerateFast(masm_);
3214 __ b(&done); 3254 __ b(&done);
3215 3255
(...skipping 21 matching lines...) Expand all
3237 ZoneList<Expression*>* args = expr->arguments(); 3277 ZoneList<Expression*>* args = expr->arguments();
3238 DCHECK(args->length() == 2); 3278 DCHECK(args->length() == 2);
3239 VisitForStackValue(args->at(0)); 3279 VisitForStackValue(args->at(0));
3240 VisitForAccumulatorValue(args->at(1)); 3280 VisitForAccumulatorValue(args->at(1));
3241 3281
3242 Register object = r4; 3282 Register object = r4;
3243 Register index = r3; 3283 Register index = r3;
3244 Register scratch = r6; 3284 Register scratch = r6;
3245 Register result = r3; 3285 Register result = r3;
3246 3286
3247 __ pop(object); 3287 PopOperand(object);
3248 3288
3249 Label need_conversion; 3289 Label need_conversion;
3250 Label index_out_of_range; 3290 Label index_out_of_range;
3251 Label done; 3291 Label done;
3252 StringCharAtGenerator generator(object, index, scratch, result, 3292 StringCharAtGenerator generator(object, index, scratch, result,
3253 &need_conversion, &need_conversion, 3293 &need_conversion, &need_conversion,
3254 &index_out_of_range, STRING_INDEX_IS_NUMBER); 3294 &index_out_of_range, STRING_INDEX_IS_NUMBER);
3255 generator.GenerateFast(masm_); 3295 generator.GenerateFast(masm_);
3256 __ b(&done); 3296 __ b(&done);
3257 3297
(...skipping 24 matching lines...) Expand all
3282 for (Expression* const arg : *args) { 3322 for (Expression* const arg : *args) {
3283 VisitForStackValue(arg); 3323 VisitForStackValue(arg);
3284 } 3324 }
3285 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3325 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3286 // Move target to r4. 3326 // Move target to r4.
3287 int const argc = args->length() - 2; 3327 int const argc = args->length() - 2;
3288 __ LoadP(r4, MemOperand(sp, (argc + 1) * kPointerSize)); 3328 __ LoadP(r4, MemOperand(sp, (argc + 1) * kPointerSize));
3289 // Call the target. 3329 // Call the target.
3290 __ mov(r3, Operand(argc)); 3330 __ mov(r3, Operand(argc));
3291 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3331 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3332 OperandStackDepthDecrement(argc + 1);
3292 // Restore context register. 3333 // Restore context register.
3293 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3334 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3294 // Discard the function left on TOS. 3335 // Discard the function left on TOS.
3295 context()->DropAndPlug(1, r3); 3336 context()->DropAndPlug(1, r3);
3296 } 3337 }
3297 3338
3298 3339
3299 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3340 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3300 ZoneList<Expression*>* args = expr->arguments(); 3341 ZoneList<Expression*>* args = expr->arguments();
3301 VisitForAccumulatorValue(args->at(0)); 3342 VisitForAccumulatorValue(args->at(0));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3368 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); 3409 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex);
3369 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); 3410 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0);
3370 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); 3411 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0);
3371 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); 3412 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
3372 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0); 3413 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0);
3373 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0); 3414 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0);
3374 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3415 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3375 __ b(&done); 3416 __ b(&done);
3376 3417
3377 __ bind(&runtime); 3418 __ bind(&runtime);
3378 __ CallRuntime(Runtime::kCreateIterResultObject); 3419 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3379 3420
3380 __ bind(&done); 3421 __ bind(&done);
3381 context()->Plug(r3); 3422 context()->Plug(r3);
3382 } 3423 }
3383 3424
3384 3425
3385 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3426 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3386 // Push undefined as the receiver. 3427 // Push undefined as the receiver.
3387 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); 3428 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
3388 __ push(r3); 3429 PushOperand(r3);
3389 3430
3390 __ LoadNativeContextSlot(expr->context_index(), r3); 3431 __ LoadNativeContextSlot(expr->context_index(), r3);
3391 } 3432 }
3392 3433
3393 3434
3394 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3435 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3395 ZoneList<Expression*>* args = expr->arguments(); 3436 ZoneList<Expression*>* args = expr->arguments();
3396 int arg_count = args->length(); 3437 int arg_count = args->length();
3397 3438
3398 SetCallPosition(expr); 3439 SetCallPosition(expr);
3399 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 3440 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
3400 __ mov(r3, Operand(arg_count)); 3441 __ mov(r3, Operand(arg_count));
3401 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3442 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3402 RelocInfo::CODE_TARGET); 3443 RelocInfo::CODE_TARGET);
3444 OperandStackDepthDecrement(arg_count + 1);
3403 } 3445 }
3404 3446
3405 3447
3406 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3448 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3407 ZoneList<Expression*>* args = expr->arguments(); 3449 ZoneList<Expression*>* args = expr->arguments();
3408 int arg_count = args->length(); 3450 int arg_count = args->length();
3409 3451
3410 if (expr->is_jsruntime()) { 3452 if (expr->is_jsruntime()) {
3411 Comment cmnt(masm_, "[ CallRuntime"); 3453 Comment cmnt(masm_, "[ CallRuntime");
3412 EmitLoadJSRuntimeFunction(expr); 3454 EmitLoadJSRuntimeFunction(expr);
3413 3455
3414 // Push the target function under the receiver. 3456 // Push the target function under the receiver.
3415 __ LoadP(ip, MemOperand(sp, 0)); 3457 __ LoadP(ip, MemOperand(sp, 0));
3416 __ push(ip); 3458 PushOperand(ip);
3417 __ StoreP(r3, MemOperand(sp, kPointerSize)); 3459 __ StoreP(r3, MemOperand(sp, kPointerSize));
3418 3460
3419 // Push the arguments ("left-to-right"). 3461 // Push the arguments ("left-to-right").
3420 for (int i = 0; i < arg_count; i++) { 3462 for (int i = 0; i < arg_count; i++) {
3421 VisitForStackValue(args->at(i)); 3463 VisitForStackValue(args->at(i));
3422 } 3464 }
3423 3465
3424 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3466 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3425 EmitCallJSRuntimeFunction(expr); 3467 EmitCallJSRuntimeFunction(expr);
3426 3468
(...skipping 15 matching lines...) Expand all
3442 default: { 3484 default: {
3443 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3485 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3444 // Push the arguments ("left-to-right"). 3486 // Push the arguments ("left-to-right").
3445 for (int i = 0; i < arg_count; i++) { 3487 for (int i = 0; i < arg_count; i++) {
3446 VisitForStackValue(args->at(i)); 3488 VisitForStackValue(args->at(i));
3447 } 3489 }
3448 3490
3449 // Call the C runtime function. 3491 // Call the C runtime function.
3450 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3492 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3451 __ CallRuntime(expr->function(), arg_count); 3493 __ CallRuntime(expr->function(), arg_count);
3494 OperandStackDepthDecrement(arg_count);
3452 context()->Plug(r3); 3495 context()->Plug(r3);
3453 } 3496 }
3454 } 3497 }
3455 } 3498 }
3456 } 3499 }
3457 3500
3458 3501
3459 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3502 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3460 switch (expr->op()) { 3503 switch (expr->op()) {
3461 case Token::DELETE: { 3504 case Token::DELETE: {
3462 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3505 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3463 Property* property = expr->expression()->AsProperty(); 3506 Property* property = expr->expression()->AsProperty();
3464 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3507 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3465 3508
3466 if (property != NULL) { 3509 if (property != NULL) {
3467 VisitForStackValue(property->obj()); 3510 VisitForStackValue(property->obj());
3468 VisitForStackValue(property->key()); 3511 VisitForStackValue(property->key());
3469 __ CallRuntime(is_strict(language_mode()) 3512 CallRuntimeWithOperands(is_strict(language_mode())
3470 ? Runtime::kDeleteProperty_Strict 3513 ? Runtime::kDeleteProperty_Strict
3471 : Runtime::kDeleteProperty_Sloppy); 3514 : Runtime::kDeleteProperty_Sloppy);
3472 context()->Plug(r3); 3515 context()->Plug(r3);
3473 } else if (proxy != NULL) { 3516 } else if (proxy != NULL) {
3474 Variable* var = proxy->var(); 3517 Variable* var = proxy->var();
3475 // Delete of an unqualified identifier is disallowed in strict mode but 3518 // Delete of an unqualified identifier is disallowed in strict mode but
3476 // "delete this" is allowed. 3519 // "delete this" is allowed.
3477 bool is_this = var->HasThisName(isolate()); 3520 bool is_this = var->HasThisName(isolate());
3478 DCHECK(is_sloppy(language_mode()) || is_this); 3521 DCHECK(is_sloppy(language_mode()) || is_this);
3479 if (var->IsUnallocatedOrGlobalSlot()) { 3522 if (var->IsUnallocatedOrGlobalSlot()) {
3480 __ LoadGlobalObject(r5); 3523 __ LoadGlobalObject(r5);
3481 __ mov(r4, Operand(var->name())); 3524 __ mov(r4, Operand(var->name()));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3523 context()->Plug(test->true_label(), test->false_label()); 3566 context()->Plug(test->true_label(), test->false_label());
3524 } else { 3567 } else {
3525 // We handle value contexts explicitly rather than simply visiting 3568 // We handle value contexts explicitly rather than simply visiting
3526 // for control and plugging the control flow into the context, 3569 // for control and plugging the control flow into the context,
3527 // because we need to prepare a pair of extra administrative AST ids 3570 // because we need to prepare a pair of extra administrative AST ids
3528 // for the optimizing compiler. 3571 // for the optimizing compiler.
3529 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3572 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3530 Label materialize_true, materialize_false, done; 3573 Label materialize_true, materialize_false, done;
3531 VisitForControl(expr->expression(), &materialize_false, 3574 VisitForControl(expr->expression(), &materialize_false,
3532 &materialize_true, &materialize_true); 3575 &materialize_true, &materialize_true);
3576 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3533 __ bind(&materialize_true); 3577 __ bind(&materialize_true);
3534 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3578 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3535 __ LoadRoot(r3, Heap::kTrueValueRootIndex); 3579 __ LoadRoot(r3, Heap::kTrueValueRootIndex);
3536 if (context()->IsStackValue()) __ push(r3); 3580 if (context()->IsStackValue()) __ push(r3);
3537 __ b(&done); 3581 __ b(&done);
3538 __ bind(&materialize_false); 3582 __ bind(&materialize_false);
3539 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3583 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
3540 __ LoadRoot(r3, Heap::kFalseValueRootIndex); 3584 __ LoadRoot(r3, Heap::kFalseValueRootIndex);
3541 if (context()->IsStackValue()) __ push(r3); 3585 if (context()->IsStackValue()) __ push(r3);
3542 __ bind(&done); 3586 __ bind(&done);
(...skipping 30 matching lines...) Expand all
3573 3617
3574 // Evaluate expression and get value. 3618 // Evaluate expression and get value.
3575 if (assign_type == VARIABLE) { 3619 if (assign_type == VARIABLE) {
3576 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3620 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3577 AccumulatorValueContext context(this); 3621 AccumulatorValueContext context(this);
3578 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3622 EmitVariableLoad(expr->expression()->AsVariableProxy());
3579 } else { 3623 } else {
3580 // Reserve space for result of postfix operation. 3624 // Reserve space for result of postfix operation.
3581 if (expr->is_postfix() && !context()->IsEffect()) { 3625 if (expr->is_postfix() && !context()->IsEffect()) {
3582 __ LoadSmiLiteral(ip, Smi::FromInt(0)); 3626 __ LoadSmiLiteral(ip, Smi::FromInt(0));
3583 __ push(ip); 3627 PushOperand(ip);
3584 } 3628 }
3585 switch (assign_type) { 3629 switch (assign_type) {
3586 case NAMED_PROPERTY: { 3630 case NAMED_PROPERTY: {
3587 // Put the object both on the stack and in the register. 3631 // Put the object both on the stack and in the register.
3588 VisitForStackValue(prop->obj()); 3632 VisitForStackValue(prop->obj());
3589 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 3633 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
3590 EmitNamedPropertyLoad(prop); 3634 EmitNamedPropertyLoad(prop);
3591 break; 3635 break;
3592 } 3636 }
3593 3637
3594 case NAMED_SUPER_PROPERTY: { 3638 case NAMED_SUPER_PROPERTY: {
3595 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3639 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3596 VisitForAccumulatorValue( 3640 VisitForAccumulatorValue(
3597 prop->obj()->AsSuperPropertyReference()->home_object()); 3641 prop->obj()->AsSuperPropertyReference()->home_object());
3598 __ Push(result_register()); 3642 PushOperand(result_register());
3599 const Register scratch = r4; 3643 const Register scratch = r4;
3600 __ LoadP(scratch, MemOperand(sp, kPointerSize)); 3644 __ LoadP(scratch, MemOperand(sp, kPointerSize));
3601 __ Push(scratch, result_register()); 3645 PushOperands(scratch, result_register());
3602 EmitNamedSuperPropertyLoad(prop); 3646 EmitNamedSuperPropertyLoad(prop);
3603 break; 3647 break;
3604 } 3648 }
3605 3649
3606 case KEYED_SUPER_PROPERTY: { 3650 case KEYED_SUPER_PROPERTY: {
3607 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3651 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3608 VisitForAccumulatorValue( 3652 VisitForAccumulatorValue(
3609 prop->obj()->AsSuperPropertyReference()->home_object()); 3653 prop->obj()->AsSuperPropertyReference()->home_object());
3610 const Register scratch = r4; 3654 const Register scratch = r4;
3611 const Register scratch1 = r5; 3655 const Register scratch1 = r5;
3612 __ mr(scratch, result_register()); 3656 __ mr(scratch, result_register());
3613 VisitForAccumulatorValue(prop->key()); 3657 VisitForAccumulatorValue(prop->key());
3614 __ Push(scratch, result_register()); 3658 PushOperands(scratch, result_register());
3615 __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize)); 3659 __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize));
3616 __ Push(scratch1, scratch, result_register()); 3660 PushOperands(scratch1, scratch, result_register());
3617 EmitKeyedSuperPropertyLoad(prop); 3661 EmitKeyedSuperPropertyLoad(prop);
3618 break; 3662 break;
3619 } 3663 }
3620 3664
3621 case KEYED_PROPERTY: { 3665 case KEYED_PROPERTY: {
3622 VisitForStackValue(prop->obj()); 3666 VisitForStackValue(prop->obj());
3623 VisitForStackValue(prop->key()); 3667 VisitForStackValue(prop->key());
3624 __ LoadP(LoadDescriptor::ReceiverRegister(), 3668 __ LoadP(LoadDescriptor::ReceiverRegister(),
3625 MemOperand(sp, 1 * kPointerSize)); 3669 MemOperand(sp, 1 * kPointerSize));
3626 __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); 3670 __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3693 } 3737 }
3694 3738
3695 // Save result for postfix expressions. 3739 // Save result for postfix expressions.
3696 if (expr->is_postfix()) { 3740 if (expr->is_postfix()) {
3697 if (!context()->IsEffect()) { 3741 if (!context()->IsEffect()) {
3698 // Save the result on the stack. If we have a named or keyed property 3742 // Save the result on the stack. If we have a named or keyed property
3699 // we store the result under the receiver that is currently on top 3743 // we store the result under the receiver that is currently on top
3700 // of the stack. 3744 // of the stack.
3701 switch (assign_type) { 3745 switch (assign_type) {
3702 case VARIABLE: 3746 case VARIABLE:
3703 __ push(r3); 3747 PushOperand(r3);
3704 break; 3748 break;
3705 case NAMED_PROPERTY: 3749 case NAMED_PROPERTY:
3706 __ StoreP(r3, MemOperand(sp, kPointerSize)); 3750 __ StoreP(r3, MemOperand(sp, kPointerSize));
3707 break; 3751 break;
3708 case NAMED_SUPER_PROPERTY: 3752 case NAMED_SUPER_PROPERTY:
3709 __ StoreP(r3, MemOperand(sp, 2 * kPointerSize)); 3753 __ StoreP(r3, MemOperand(sp, 2 * kPointerSize));
3710 break; 3754 break;
3711 case KEYED_PROPERTY: 3755 case KEYED_PROPERTY:
3712 __ StoreP(r3, MemOperand(sp, 2 * kPointerSize)); 3756 __ StoreP(r3, MemOperand(sp, 2 * kPointerSize));
3713 break; 3757 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3751 } else { 3795 } else {
3752 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3796 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3753 Token::ASSIGN, expr->CountSlot()); 3797 Token::ASSIGN, expr->CountSlot());
3754 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3798 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3755 context()->Plug(r3); 3799 context()->Plug(r3);
3756 } 3800 }
3757 break; 3801 break;
3758 case NAMED_PROPERTY: { 3802 case NAMED_PROPERTY: {
3759 __ mov(StoreDescriptor::NameRegister(), 3803 __ mov(StoreDescriptor::NameRegister(),
3760 Operand(prop->key()->AsLiteral()->value())); 3804 Operand(prop->key()->AsLiteral()->value()));
3761 __ pop(StoreDescriptor::ReceiverRegister()); 3805 PopOperand(StoreDescriptor::ReceiverRegister());
3762 EmitLoadStoreICSlot(expr->CountSlot()); 3806 EmitLoadStoreICSlot(expr->CountSlot());
3763 CallStoreIC(); 3807 CallStoreIC();
3764 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3808 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3765 if (expr->is_postfix()) { 3809 if (expr->is_postfix()) {
3766 if (!context()->IsEffect()) { 3810 if (!context()->IsEffect()) {
3767 context()->PlugTOS(); 3811 context()->PlugTOS();
3768 } 3812 }
3769 } else { 3813 } else {
3770 context()->Plug(r3); 3814 context()->Plug(r3);
3771 } 3815 }
(...skipping 15 matching lines...) Expand all
3787 if (expr->is_postfix()) { 3831 if (expr->is_postfix()) {
3788 if (!context()->IsEffect()) { 3832 if (!context()->IsEffect()) {
3789 context()->PlugTOS(); 3833 context()->PlugTOS();
3790 } 3834 }
3791 } else { 3835 } else {
3792 context()->Plug(r3); 3836 context()->Plug(r3);
3793 } 3837 }
3794 break; 3838 break;
3795 } 3839 }
3796 case KEYED_PROPERTY: { 3840 case KEYED_PROPERTY: {
3797 __ Pop(StoreDescriptor::ReceiverRegister(), 3841 PopOperands(StoreDescriptor::ReceiverRegister(),
3798 StoreDescriptor::NameRegister()); 3842 StoreDescriptor::NameRegister());
3799 Handle<Code> ic = 3843 Handle<Code> ic =
3800 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3844 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3801 EmitLoadStoreICSlot(expr->CountSlot()); 3845 EmitLoadStoreICSlot(expr->CountSlot());
3802 CallIC(ic); 3846 CallIC(ic);
3803 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3847 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3804 if (expr->is_postfix()) { 3848 if (expr->is_postfix()) {
3805 if (!context()->IsEffect()) { 3849 if (!context()->IsEffect()) {
3806 context()->PlugTOS(); 3850 context()->PlugTOS();
3807 } 3851 }
3808 } else { 3852 } else {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3912 Label* if_false = NULL; 3956 Label* if_false = NULL;
3913 Label* fall_through = NULL; 3957 Label* fall_through = NULL;
3914 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, 3958 context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
3915 &if_false, &fall_through); 3959 &if_false, &fall_through);
3916 3960
3917 Token::Value op = expr->op(); 3961 Token::Value op = expr->op();
3918 VisitForStackValue(expr->left()); 3962 VisitForStackValue(expr->left());
3919 switch (op) { 3963 switch (op) {
3920 case Token::IN: 3964 case Token::IN:
3921 VisitForStackValue(expr->right()); 3965 VisitForStackValue(expr->right());
3922 __ CallRuntime(Runtime::kHasProperty); 3966 CallRuntimeWithOperands(Runtime::kHasProperty);
3923 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3967 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3924 __ CompareRoot(r3, Heap::kTrueValueRootIndex); 3968 __ CompareRoot(r3, Heap::kTrueValueRootIndex);
3925 Split(eq, if_true, if_false, fall_through); 3969 Split(eq, if_true, if_false, fall_through);
3926 break; 3970 break;
3927 3971
3928 case Token::INSTANCEOF: { 3972 case Token::INSTANCEOF: {
3929 VisitForAccumulatorValue(expr->right()); 3973 VisitForAccumulatorValue(expr->right());
3930 __ pop(r4); 3974 PopOperand(r4);
3931 InstanceOfStub stub(isolate()); 3975 InstanceOfStub stub(isolate());
3932 __ CallStub(&stub); 3976 __ CallStub(&stub);
3933 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3977 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3934 __ CompareRoot(r3, Heap::kTrueValueRootIndex); 3978 __ CompareRoot(r3, Heap::kTrueValueRootIndex);
3935 Split(eq, if_true, if_false, fall_through); 3979 Split(eq, if_true, if_false, fall_through);
3936 break; 3980 break;
3937 } 3981 }
3938 3982
3939 default: { 3983 default: {
3940 VisitForAccumulatorValue(expr->right()); 3984 VisitForAccumulatorValue(expr->right());
3941 Condition cond = CompareIC::ComputeCondition(op); 3985 Condition cond = CompareIC::ComputeCondition(op);
3942 __ pop(r4); 3986 PopOperand(r4);
3943 3987
3944 bool inline_smi_code = ShouldInlineSmiCase(op); 3988 bool inline_smi_code = ShouldInlineSmiCase(op);
3945 JumpPatchSite patch_site(masm_); 3989 JumpPatchSite patch_site(masm_);
3946 if (inline_smi_code) { 3990 if (inline_smi_code) {
3947 Label slow_case; 3991 Label slow_case;
3948 __ orx(r5, r3, r4); 3992 __ orx(r5, r3, r4);
3949 patch_site.EmitJumpIfNotSmi(r5, &slow_case); 3993 patch_site.EmitJumpIfNotSmi(r5, &slow_case);
3950 __ cmp(r4, r3); 3994 __ cmp(r4, r3);
3951 Split(cond, if_true, if_false, NULL); 3995 Split(cond, if_true, if_false, NULL);
3952 __ bind(&slow_case); 3996 __ bind(&slow_case);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
4029 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, ip); 4073 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, ip);
4030 } else if (closure_scope->is_eval_scope()) { 4074 } else if (closure_scope->is_eval_scope()) {
4031 // Contexts created by a call to eval have the same closure as the 4075 // Contexts created by a call to eval have the same closure as the
4032 // context calling eval, not the anonymous closure containing the eval 4076 // context calling eval, not the anonymous closure containing the eval
4033 // code. Fetch it from the context. 4077 // code. Fetch it from the context.
4034 __ LoadP(ip, ContextMemOperand(cp, Context::CLOSURE_INDEX)); 4078 __ LoadP(ip, ContextMemOperand(cp, Context::CLOSURE_INDEX));
4035 } else { 4079 } else {
4036 DCHECK(closure_scope->is_function_scope()); 4080 DCHECK(closure_scope->is_function_scope());
4037 __ LoadP(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4081 __ LoadP(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4038 } 4082 }
4039 __ push(ip); 4083 PushOperand(ip);
4040 } 4084 }
4041 4085
4042 4086
4043 // ---------------------------------------------------------------------------- 4087 // ----------------------------------------------------------------------------
4044 // Non-local control flow support. 4088 // Non-local control flow support.
4045 4089
4046 void FullCodeGenerator::EnterFinallyBlock() { 4090 void FullCodeGenerator::EnterFinallyBlock() {
4047 DCHECK(!result_register().is(r4)); 4091 DCHECK(!result_register().is(r4));
4048 // Store pending message while executing finally block. 4092 // Store pending message while executing finally block.
4049 ExternalReference pending_message_obj = 4093 ExternalReference pending_message_obj =
4050 ExternalReference::address_of_pending_message_obj(isolate()); 4094 ExternalReference::address_of_pending_message_obj(isolate());
4051 __ mov(ip, Operand(pending_message_obj)); 4095 __ mov(ip, Operand(pending_message_obj));
4052 __ LoadP(r4, MemOperand(ip)); 4096 __ LoadP(r4, MemOperand(ip));
4053 __ push(r4); 4097 PushOperand(r4);
4054 4098
4055 ClearPendingMessage(); 4099 ClearPendingMessage();
4056 } 4100 }
4057 4101
4058 4102
4059 void FullCodeGenerator::ExitFinallyBlock() { 4103 void FullCodeGenerator::ExitFinallyBlock() {
4060 DCHECK(!result_register().is(r4)); 4104 DCHECK(!result_register().is(r4));
4061 // Restore pending message from stack. 4105 // Restore pending message from stack.
4062 __ pop(r4); 4106 PopOperand(r4);
4063 ExternalReference pending_message_obj = 4107 ExternalReference pending_message_obj =
4064 ExternalReference::address_of_pending_message_obj(isolate()); 4108 ExternalReference::address_of_pending_message_obj(isolate());
4065 __ mov(ip, Operand(pending_message_obj)); 4109 __ mov(ip, Operand(pending_message_obj));
4066 __ StoreP(r4, MemOperand(ip)); 4110 __ StoreP(r4, MemOperand(ip));
4067 } 4111 }
4068 4112
4069 4113
4070 void FullCodeGenerator::ClearPendingMessage() { 4114 void FullCodeGenerator::ClearPendingMessage() {
4071 DCHECK(!result_register().is(r4)); 4115 DCHECK(!result_register().is(r4));
4072 ExternalReference pending_message_obj = 4116 ExternalReference pending_message_obj =
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
4178 return ON_STACK_REPLACEMENT; 4222 return ON_STACK_REPLACEMENT;
4179 } 4223 }
4180 4224
4181 DCHECK(interrupt_address == 4225 DCHECK(interrupt_address ==
4182 isolate->builtins()->OsrAfterStackCheck()->entry()); 4226 isolate->builtins()->OsrAfterStackCheck()->entry());
4183 return OSR_AFTER_STACK_CHECK; 4227 return OSR_AFTER_STACK_CHECK;
4184 } 4228 }
4185 } // namespace internal 4229 } // namespace internal
4186 } // namespace v8 4230 } // namespace v8
4187 #endif // V8_TARGET_ARCH_PPC 4231 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698