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

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

Issue 1706283002: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Turn off verification. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/ppc/full-codegen-ppc.cc ('k') | src/full-codegen/x87/full-codegen-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // the frame (that is done below). 111 // the frame (that is done below).
112 FrameScope frame_scope(masm_, StackFrame::MANUAL); 112 FrameScope frame_scope(masm_, StackFrame::MANUAL);
113 113
114 info->set_prologue_offset(masm_->pc_offset()); 114 info->set_prologue_offset(masm_->pc_offset());
115 __ Prologue(info->GeneratePreagedPrologue()); 115 __ Prologue(info->GeneratePreagedPrologue());
116 116
117 { Comment cmnt(masm_, "[ Allocate locals"); 117 { Comment cmnt(masm_, "[ Allocate locals");
118 int locals_count = info->scope()->num_stack_slots(); 118 int locals_count = info->scope()->num_stack_slots();
119 // Generators allocate locals, if any, in context slots. 119 // Generators allocate locals, if any, in context slots.
120 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 120 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
121 OperandStackDepthIncrement(locals_count);
121 if (locals_count == 1) { 122 if (locals_count == 1) {
122 __ PushRoot(Heap::kUndefinedValueRootIndex); 123 __ PushRoot(Heap::kUndefinedValueRootIndex);
123 } else if (locals_count > 1) { 124 } else if (locals_count > 1) {
124 if (locals_count >= 128) { 125 if (locals_count >= 128) {
125 Label ok; 126 Label ok;
126 __ movp(rcx, rsp); 127 __ movp(rcx, rsp);
127 __ subp(rcx, Immediate(locals_count * kPointerSize)); 128 __ subp(rcx, Immediate(locals_count * kPointerSize));
128 __ CompareRoot(rcx, Heap::kRealStackLimitRootIndex); 129 __ CompareRoot(rcx, Heap::kRealStackLimitRootIndex);
129 __ j(above_equal, &ok, Label::kNear); 130 __ j(above_equal, &ok, Label::kNear);
130 __ CallRuntime(Runtime::kThrowStackOverflow); 131 __ CallRuntime(Runtime::kThrowStackOverflow);
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 int arg_count = info_->scope()->num_parameters() + 1; 425 int arg_count = info_->scope()->num_parameters() + 1;
425 int arguments_bytes = arg_count * kPointerSize; 426 int arguments_bytes = arg_count * kPointerSize;
426 __ Ret(arguments_bytes, rcx); 427 __ Ret(arguments_bytes, rcx);
427 } 428 }
428 } 429 }
429 430
430 431
431 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 432 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
432 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 433 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
433 MemOperand operand = codegen()->VarOperand(var, result_register()); 434 MemOperand operand = codegen()->VarOperand(var, result_register());
434 __ Push(operand); 435 codegen()->PushOperand(operand);
435 } 436 }
436 437
437 438
438 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 439 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
439 } 440 }
440 441
441 442
442 void FullCodeGenerator::AccumulatorValueContext::Plug( 443 void FullCodeGenerator::AccumulatorValueContext::Plug(
443 Heap::RootListIndex index) const { 444 Heap::RootListIndex index) const {
444 __ LoadRoot(result_register(), index); 445 __ LoadRoot(result_register(), index);
445 } 446 }
446 447
447 448
448 void FullCodeGenerator::StackValueContext::Plug( 449 void FullCodeGenerator::StackValueContext::Plug(
449 Heap::RootListIndex index) const { 450 Heap::RootListIndex index) const {
451 codegen()->OperandStackDepthIncrement(1);
450 __ PushRoot(index); 452 __ PushRoot(index);
451 } 453 }
452 454
453 455
454 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 456 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
455 codegen()->PrepareForBailoutBeforeSplit(condition(), 457 codegen()->PrepareForBailoutBeforeSplit(condition(),
456 true, 458 true,
457 true_label_, 459 true_label_,
458 false_label_); 460 false_label_);
459 if (index == Heap::kUndefinedValueRootIndex || 461 if (index == Heap::kUndefinedValueRootIndex ||
(...skipping 17 matching lines...) Expand all
477 Handle<Object> lit) const { 479 Handle<Object> lit) const {
478 if (lit->IsSmi()) { 480 if (lit->IsSmi()) {
479 __ SafeMove(result_register(), Smi::cast(*lit)); 481 __ SafeMove(result_register(), Smi::cast(*lit));
480 } else { 482 } else {
481 __ Move(result_register(), lit); 483 __ Move(result_register(), lit);
482 } 484 }
483 } 485 }
484 486
485 487
486 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 488 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
489 codegen()->OperandStackDepthIncrement(1);
487 if (lit->IsSmi()) { 490 if (lit->IsSmi()) {
488 __ SafePush(Smi::cast(*lit)); 491 __ SafePush(Smi::cast(*lit));
489 } else { 492 } else {
490 __ Push(lit); 493 __ Push(lit);
491 } 494 }
492 } 495 }
493 496
494 497
495 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 498 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
496 codegen()->PrepareForBailoutBeforeSplit(condition(), 499 codegen()->PrepareForBailoutBeforeSplit(condition(),
(...skipping 18 matching lines...) Expand all
515 if (true_label_ != fall_through_) __ jmp(true_label_); 518 if (true_label_ != fall_through_) __ jmp(true_label_);
516 } 519 }
517 } else { 520 } else {
518 // For simplicity we always test the accumulator register. 521 // For simplicity we always test the accumulator register.
519 __ Move(result_register(), lit); 522 __ Move(result_register(), lit);
520 codegen()->DoTest(this); 523 codegen()->DoTest(this);
521 } 524 }
522 } 525 }
523 526
524 527
525 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
526 Register reg) const {
527 DCHECK(count > 0);
528 __ Drop(count);
529 }
530
531
532 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
533 int count,
534 Register reg) const {
535 DCHECK(count > 0);
536 __ Drop(count);
537 __ Move(result_register(), reg);
538 }
539
540
541 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 528 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
542 Register reg) const { 529 Register reg) const {
543 DCHECK(count > 0); 530 DCHECK(count > 0);
544 if (count > 1) __ Drop(count - 1); 531 if (count > 1) codegen()->DropOperands(count - 1);
545 __ movp(Operand(rsp, 0), reg); 532 __ movp(Operand(rsp, 0), reg);
546 } 533 }
547 534
548 535
549 void FullCodeGenerator::TestContext::DropAndPlug(int count,
550 Register reg) const {
551 DCHECK(count > 0);
552 // For simplicity we always test the accumulator register.
553 __ Drop(count);
554 __ Move(result_register(), reg);
555 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
556 codegen()->DoTest(this);
557 }
558
559
560 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 536 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
561 Label* materialize_false) const { 537 Label* materialize_false) const {
562 DCHECK(materialize_true == materialize_false); 538 DCHECK(materialize_true == materialize_false);
563 __ bind(materialize_true); 539 __ bind(materialize_true);
564 } 540 }
565 541
566 542
567 void FullCodeGenerator::AccumulatorValueContext::Plug( 543 void FullCodeGenerator::AccumulatorValueContext::Plug(
568 Label* materialize_true, 544 Label* materialize_true,
569 Label* materialize_false) const { 545 Label* materialize_false) const {
570 Label done; 546 Label done;
571 __ bind(materialize_true); 547 __ bind(materialize_true);
572 __ Move(result_register(), isolate()->factory()->true_value()); 548 __ Move(result_register(), isolate()->factory()->true_value());
573 __ jmp(&done, Label::kNear); 549 __ jmp(&done, Label::kNear);
574 __ bind(materialize_false); 550 __ bind(materialize_false);
575 __ Move(result_register(), isolate()->factory()->false_value()); 551 __ Move(result_register(), isolate()->factory()->false_value());
576 __ bind(&done); 552 __ bind(&done);
577 } 553 }
578 554
579 555
580 void FullCodeGenerator::StackValueContext::Plug( 556 void FullCodeGenerator::StackValueContext::Plug(
581 Label* materialize_true, 557 Label* materialize_true,
582 Label* materialize_false) const { 558 Label* materialize_false) const {
559 codegen()->OperandStackDepthIncrement(1);
583 Label done; 560 Label done;
584 __ bind(materialize_true); 561 __ bind(materialize_true);
585 __ Push(isolate()->factory()->true_value()); 562 __ Push(isolate()->factory()->true_value());
586 __ jmp(&done, Label::kNear); 563 __ jmp(&done, Label::kNear);
587 __ bind(materialize_false); 564 __ bind(materialize_false);
588 __ Push(isolate()->factory()->false_value()); 565 __ Push(isolate()->factory()->false_value());
589 __ bind(&done); 566 __ bind(&done);
590 } 567 }
591 568
592 569
593 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 570 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
594 Label* materialize_false) const { 571 Label* materialize_false) const {
595 DCHECK(materialize_true == true_label_); 572 DCHECK(materialize_true == true_label_);
596 DCHECK(materialize_false == false_label_); 573 DCHECK(materialize_false == false_label_);
597 } 574 }
598 575
599 576
600 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 577 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
601 Heap::RootListIndex value_root_index = 578 Heap::RootListIndex value_root_index =
602 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 579 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
603 __ LoadRoot(result_register(), value_root_index); 580 __ LoadRoot(result_register(), value_root_index);
604 } 581 }
605 582
606 583
607 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 584 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
585 codegen()->OperandStackDepthIncrement(1);
608 Heap::RootListIndex value_root_index = 586 Heap::RootListIndex value_root_index =
609 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 587 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
610 __ PushRoot(value_root_index); 588 __ PushRoot(value_root_index);
611 } 589 }
612 590
613 591
614 void FullCodeGenerator::TestContext::Plug(bool flag) const { 592 void FullCodeGenerator::TestContext::Plug(bool flag) const {
615 codegen()->PrepareForBailoutBeforeSplit(condition(), 593 codegen()->PrepareForBailoutBeforeSplit(condition(),
616 true, 594 true,
617 true_label_, 595 true_label_,
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 rcx, 813 rcx,
836 kDontSaveFPRegs, 814 kDontSaveFPRegs,
837 EMIT_REMEMBERED_SET, 815 EMIT_REMEMBERED_SET,
838 OMIT_SMI_CHECK); 816 OMIT_SMI_CHECK);
839 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 817 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
840 break; 818 break;
841 } 819 }
842 820
843 case VariableLocation::LOOKUP: { 821 case VariableLocation::LOOKUP: {
844 Comment cmnt(masm_, "[ FunctionDeclaration"); 822 Comment cmnt(masm_, "[ FunctionDeclaration");
845 __ Push(variable->name()); 823 PushOperand(variable->name());
846 VisitForStackValue(declaration->fun()); 824 VisitForStackValue(declaration->fun());
847 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 825 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
848 __ CallRuntime(Runtime::kDeclareLookupSlot); 826 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
849 break; 827 break;
850 } 828 }
851 } 829 }
852 } 830 }
853 831
854 832
855 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 833 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
856 // Call the runtime to declare the globals. 834 // Call the runtime to declare the globals.
857 __ Push(pairs); 835 __ Push(pairs);
858 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 836 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 913
936 __ testp(rax, rax); 914 __ testp(rax, rax);
937 __ j(not_equal, &next_test); 915 __ j(not_equal, &next_test);
938 __ Drop(1); // Switch value is no longer needed. 916 __ Drop(1); // Switch value is no longer needed.
939 __ jmp(clause->body_target()); 917 __ jmp(clause->body_target());
940 } 918 }
941 919
942 // Discard the test value and jump to the default if present, otherwise to 920 // Discard the test value and jump to the default if present, otherwise to
943 // the end of the statement. 921 // the end of the statement.
944 __ bind(&next_test); 922 __ bind(&next_test);
945 __ Drop(1); // Switch value is no longer needed. 923 DropOperands(1); // Switch value is no longer needed.
946 if (default_clause == NULL) { 924 if (default_clause == NULL) {
947 __ jmp(nested_statement.break_label()); 925 __ jmp(nested_statement.break_label());
948 } else { 926 } else {
949 __ jmp(default_clause->body_target()); 927 __ jmp(default_clause->body_target());
950 } 928 }
951 929
952 // Compile all the case bodies. 930 // Compile all the case bodies.
953 for (int i = 0; i < clauses->length(); i++) { 931 for (int i = 0; i < clauses->length(); i++) {
954 Comment cmnt(masm_, "[ Case body"); 932 Comment cmnt(masm_, "[ Case body");
955 CaseClause* clause = clauses->at(i); 933 CaseClause* clause = clauses->at(i);
(...skipping 13 matching lines...) Expand all
969 947
970 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 948 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
971 949
972 Label loop, exit; 950 Label loop, exit;
973 ForIn loop_statement(this, stmt); 951 ForIn loop_statement(this, stmt);
974 increment_loop_depth(); 952 increment_loop_depth();
975 953
976 // Get the object to enumerate over. 954 // Get the object to enumerate over.
977 SetExpressionAsStatementPosition(stmt->enumerable()); 955 SetExpressionAsStatementPosition(stmt->enumerable());
978 VisitForAccumulatorValue(stmt->enumerable()); 956 VisitForAccumulatorValue(stmt->enumerable());
957 OperandStackDepthIncrement(ForIn::kElementCount);
979 958
980 // If the object is null or undefined, skip over the loop, otherwise convert 959 // If the object is null or undefined, skip over the loop, otherwise convert
981 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 960 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
982 Label convert, done_convert; 961 Label convert, done_convert;
983 __ JumpIfSmi(rax, &convert, Label::kNear); 962 __ JumpIfSmi(rax, &convert, Label::kNear);
984 __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx); 963 __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx);
985 __ j(above_equal, &done_convert, Label::kNear); 964 __ j(above_equal, &done_convert, Label::kNear);
986 __ CompareRoot(rax, Heap::kNullValueRootIndex); 965 __ CompareRoot(rax, Heap::kNullValueRootIndex);
987 __ j(equal, &exit); 966 __ j(equal, &exit);
988 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 967 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 // index (smi) stored on top of the stack. 1109 // index (smi) stored on top of the stack.
1131 __ bind(loop_statement.continue_label()); 1110 __ bind(loop_statement.continue_label());
1132 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); 1111 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1));
1133 1112
1134 EmitBackEdgeBookkeeping(stmt, &loop); 1113 EmitBackEdgeBookkeeping(stmt, &loop);
1135 __ jmp(&loop); 1114 __ jmp(&loop);
1136 1115
1137 // Remove the pointers stored on the stack. 1116 // Remove the pointers stored on the stack.
1138 __ bind(loop_statement.break_label()); 1117 __ bind(loop_statement.break_label());
1139 __ addp(rsp, Immediate(5 * kPointerSize)); 1118 __ addp(rsp, Immediate(5 * kPointerSize));
1119 OperandStackDepthDecrement(ForIn::kElementCount);
1140 1120
1141 // Exit and decrement the loop depth. 1121 // Exit and decrement the loop depth.
1142 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1122 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1143 __ bind(&exit); 1123 __ bind(&exit);
1144 decrement_loop_depth(); 1124 decrement_loop_depth();
1145 } 1125 }
1146 1126
1147 1127
1148 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1128 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1149 bool pretenure) { 1129 bool pretenure) {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 __ Move(rdx, Smi::FromInt(expr->flags())); 1381 __ Move(rdx, Smi::FromInt(expr->flags()));
1402 FastCloneRegExpStub stub(isolate()); 1382 FastCloneRegExpStub stub(isolate());
1403 __ CallStub(&stub); 1383 __ CallStub(&stub);
1404 context()->Plug(rax); 1384 context()->Plug(rax);
1405 } 1385 }
1406 1386
1407 1387
1408 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1388 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1409 Expression* expression = (property == NULL) ? NULL : property->value(); 1389 Expression* expression = (property == NULL) ? NULL : property->value();
1410 if (expression == NULL) { 1390 if (expression == NULL) {
1391 OperandStackDepthIncrement(1);
1411 __ PushRoot(Heap::kNullValueRootIndex); 1392 __ PushRoot(Heap::kNullValueRootIndex);
1412 } else { 1393 } else {
1413 VisitForStackValue(expression); 1394 VisitForStackValue(expression);
1414 if (NeedsHomeObject(expression)) { 1395 if (NeedsHomeObject(expression)) {
1415 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1396 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1416 property->kind() == ObjectLiteral::Property::SETTER); 1397 property->kind() == ObjectLiteral::Property::SETTER);
1417 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1398 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1418 EmitSetHomeObject(expression, offset, property->GetSlot()); 1399 EmitSetHomeObject(expression, offset, property->GetSlot());
1419 } 1400 }
1420 } 1401 }
(...skipping 28 matching lines...) Expand all
1449 AccessorTable accessor_table(zone()); 1430 AccessorTable accessor_table(zone());
1450 int property_index = 0; 1431 int property_index = 0;
1451 for (; property_index < expr->properties()->length(); property_index++) { 1432 for (; property_index < expr->properties()->length(); property_index++) {
1452 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1433 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1453 if (property->is_computed_name()) break; 1434 if (property->is_computed_name()) break;
1454 if (property->IsCompileTimeValue()) continue; 1435 if (property->IsCompileTimeValue()) continue;
1455 1436
1456 Literal* key = property->key()->AsLiteral(); 1437 Literal* key = property->key()->AsLiteral();
1457 Expression* value = property->value(); 1438 Expression* value = property->value();
1458 if (!result_saved) { 1439 if (!result_saved) {
1459 __ Push(rax); // Save result on the stack 1440 PushOperand(rax); // Save result on the stack
1460 result_saved = true; 1441 result_saved = true;
1461 } 1442 }
1462 switch (property->kind()) { 1443 switch (property->kind()) {
1463 case ObjectLiteral::Property::CONSTANT: 1444 case ObjectLiteral::Property::CONSTANT:
1464 UNREACHABLE(); 1445 UNREACHABLE();
1465 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1446 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1466 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 1447 DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
1467 // Fall through. 1448 // Fall through.
1468 case ObjectLiteral::Property::COMPUTED: 1449 case ObjectLiteral::Property::COMPUTED:
1469 // It is safe to use [[Put]] here because the boilerplate already 1450 // It is safe to use [[Put]] here because the boilerplate already
1470 // contains computed properties with an uninitialized value. 1451 // contains computed properties with an uninitialized value.
1471 if (key->value()->IsInternalizedString()) { 1452 if (key->value()->IsInternalizedString()) {
1472 if (property->emit_store()) { 1453 if (property->emit_store()) {
1473 VisitForAccumulatorValue(value); 1454 VisitForAccumulatorValue(value);
1474 DCHECK(StoreDescriptor::ValueRegister().is(rax)); 1455 DCHECK(StoreDescriptor::ValueRegister().is(rax));
1475 __ Move(StoreDescriptor::NameRegister(), key->value()); 1456 __ Move(StoreDescriptor::NameRegister(), key->value());
1476 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); 1457 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
1477 EmitLoadStoreICSlot(property->GetSlot(0)); 1458 EmitLoadStoreICSlot(property->GetSlot(0));
1478 CallStoreIC(); 1459 CallStoreIC();
1479 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1460 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1480 1461
1481 if (NeedsHomeObject(value)) { 1462 if (NeedsHomeObject(value)) {
1482 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1463 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1483 } 1464 }
1484 } else { 1465 } else {
1485 VisitForEffect(value); 1466 VisitForEffect(value);
1486 } 1467 }
1487 break; 1468 break;
1488 } 1469 }
1489 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1470 PushOperand(Operand(rsp, 0)); // Duplicate receiver.
1490 VisitForStackValue(key); 1471 VisitForStackValue(key);
1491 VisitForStackValue(value); 1472 VisitForStackValue(value);
1492 if (property->emit_store()) { 1473 if (property->emit_store()) {
1493 if (NeedsHomeObject(value)) { 1474 if (NeedsHomeObject(value)) {
1494 EmitSetHomeObject(value, 2, property->GetSlot()); 1475 EmitSetHomeObject(value, 2, property->GetSlot());
1495 } 1476 }
1496 __ Push(Smi::FromInt(SLOPPY)); // Language mode 1477 PushOperand(Smi::FromInt(SLOPPY)); // Language mode
1497 __ CallRuntime(Runtime::kSetProperty); 1478 CallRuntimeWithOperands(Runtime::kSetProperty);
1498 } else { 1479 } else {
1499 __ Drop(3); 1480 DropOperands(3);
1500 } 1481 }
1501 break; 1482 break;
1502 case ObjectLiteral::Property::PROTOTYPE: 1483 case ObjectLiteral::Property::PROTOTYPE:
1503 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1484 PushOperand(Operand(rsp, 0)); // Duplicate receiver.
1504 VisitForStackValue(value); 1485 VisitForStackValue(value);
1505 DCHECK(property->emit_store()); 1486 DCHECK(property->emit_store());
1506 __ CallRuntime(Runtime::kInternalSetPrototype); 1487 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1507 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1488 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1508 NO_REGISTERS); 1489 NO_REGISTERS);
1509 break; 1490 break;
1510 case ObjectLiteral::Property::GETTER: 1491 case ObjectLiteral::Property::GETTER:
1511 if (property->emit_store()) { 1492 if (property->emit_store()) {
1512 accessor_table.lookup(key)->second->getter = property; 1493 accessor_table.lookup(key)->second->getter = property;
1513 } 1494 }
1514 break; 1495 break;
1515 case ObjectLiteral::Property::SETTER: 1496 case ObjectLiteral::Property::SETTER:
1516 if (property->emit_store()) { 1497 if (property->emit_store()) {
1517 accessor_table.lookup(key)->second->setter = property; 1498 accessor_table.lookup(key)->second->setter = property;
1518 } 1499 }
1519 break; 1500 break;
1520 } 1501 }
1521 } 1502 }
1522 1503
1523 // Emit code to define accessors, using only a single call to the runtime for 1504 // Emit code to define accessors, using only a single call to the runtime for
1524 // each pair of corresponding getters and setters. 1505 // each pair of corresponding getters and setters.
1525 for (AccessorTable::Iterator it = accessor_table.begin(); 1506 for (AccessorTable::Iterator it = accessor_table.begin();
1526 it != accessor_table.end(); 1507 it != accessor_table.end();
1527 ++it) { 1508 ++it) {
1528 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1509 PushOperand(Operand(rsp, 0)); // Duplicate receiver.
1529 VisitForStackValue(it->first); 1510 VisitForStackValue(it->first);
1530 EmitAccessor(it->second->getter); 1511 EmitAccessor(it->second->getter);
1531 EmitAccessor(it->second->setter); 1512 EmitAccessor(it->second->setter);
1532 __ Push(Smi::FromInt(NONE)); 1513 PushOperand(Smi::FromInt(NONE));
1533 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1514 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1534 } 1515 }
1535 1516
1536 // Object literals have two parts. The "static" part on the left contains no 1517 // Object literals have two parts. The "static" part on the left contains no
1537 // computed property names, and so we can compute its map ahead of time; see 1518 // computed property names, and so we can compute its map ahead of time; see
1538 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1519 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1539 // starts with the first computed property name, and continues with all 1520 // starts with the first computed property name, and continues with all
1540 // properties to its right. All the code from above initializes the static 1521 // properties to its right. All the code from above initializes the static
1541 // component of the object literal, and arranges for the map of the result to 1522 // component of the object literal, and arranges for the map of the result to
1542 // reflect the static order in which the keys appear. For the dynamic 1523 // reflect the static order in which the keys appear. For the dynamic
1543 // properties, we compile them into a series of "SetOwnProperty" runtime 1524 // properties, we compile them into a series of "SetOwnProperty" runtime
1544 // calls. This will preserve insertion order. 1525 // calls. This will preserve insertion order.
1545 for (; property_index < expr->properties()->length(); property_index++) { 1526 for (; property_index < expr->properties()->length(); property_index++) {
1546 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1527 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1547 1528
1548 Expression* value = property->value(); 1529 Expression* value = property->value();
1549 if (!result_saved) { 1530 if (!result_saved) {
1550 __ Push(rax); // Save result on the stack 1531 PushOperand(rax); // Save result on the stack
1551 result_saved = true; 1532 result_saved = true;
1552 } 1533 }
1553 1534
1554 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1535 PushOperand(Operand(rsp, 0)); // Duplicate receiver.
1555 1536
1556 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1537 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1557 DCHECK(!property->is_computed_name()); 1538 DCHECK(!property->is_computed_name());
1558 VisitForStackValue(value); 1539 VisitForStackValue(value);
1559 DCHECK(property->emit_store()); 1540 DCHECK(property->emit_store());
1560 __ CallRuntime(Runtime::kInternalSetPrototype); 1541 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1561 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1542 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1562 NO_REGISTERS); 1543 NO_REGISTERS);
1563 } else { 1544 } else {
1564 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1545 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1565 VisitForStackValue(value); 1546 VisitForStackValue(value);
1566 if (NeedsHomeObject(value)) { 1547 if (NeedsHomeObject(value)) {
1567 EmitSetHomeObject(value, 2, property->GetSlot()); 1548 EmitSetHomeObject(value, 2, property->GetSlot());
1568 } 1549 }
1569 1550
1570 switch (property->kind()) { 1551 switch (property->kind()) {
1571 case ObjectLiteral::Property::CONSTANT: 1552 case ObjectLiteral::Property::CONSTANT:
1572 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1553 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1573 case ObjectLiteral::Property::COMPUTED: 1554 case ObjectLiteral::Property::COMPUTED:
1574 if (property->emit_store()) { 1555 if (property->emit_store()) {
1575 __ Push(Smi::FromInt(NONE)); 1556 PushOperand(Smi::FromInt(NONE));
1576 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1557 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1577 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1558 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1578 } else { 1559 } else {
1579 __ Drop(3); 1560 DropOperands(3);
1580 } 1561 }
1581 break; 1562 break;
1582 1563
1583 case ObjectLiteral::Property::PROTOTYPE: 1564 case ObjectLiteral::Property::PROTOTYPE:
1584 UNREACHABLE(); 1565 UNREACHABLE();
1585 break; 1566 break;
1586 1567
1587 case ObjectLiteral::Property::GETTER: 1568 case ObjectLiteral::Property::GETTER:
1588 __ Push(Smi::FromInt(NONE)); 1569 PushOperand(Smi::FromInt(NONE));
1589 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1570 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1590 break; 1571 break;
1591 1572
1592 case ObjectLiteral::Property::SETTER: 1573 case ObjectLiteral::Property::SETTER:
1593 __ Push(Smi::FromInt(NONE)); 1574 PushOperand(Smi::FromInt(NONE));
1594 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1575 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1595 break; 1576 break;
1596 } 1577 }
1597 } 1578 }
1598 } 1579 }
1599 1580
1600 if (expr->has_function()) { 1581 if (expr->has_function()) {
1601 DCHECK(result_saved); 1582 DCHECK(result_saved);
1602 __ Push(Operand(rsp, 0)); 1583 __ Push(Operand(rsp, 0));
1603 __ CallRuntime(Runtime::kToFastProperties); 1584 __ CallRuntime(Runtime::kToFastProperties);
1604 } 1585 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1649 int array_index = 0; 1630 int array_index = 0;
1650 for (; array_index < length; array_index++) { 1631 for (; array_index < length; array_index++) {
1651 Expression* subexpr = subexprs->at(array_index); 1632 Expression* subexpr = subexprs->at(array_index);
1652 DCHECK(!subexpr->IsSpread()); 1633 DCHECK(!subexpr->IsSpread());
1653 1634
1654 // If the subexpression is a literal or a simple materialized literal it 1635 // If the subexpression is a literal or a simple materialized literal it
1655 // is already set in the cloned array. 1636 // is already set in the cloned array.
1656 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1637 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1657 1638
1658 if (!result_saved) { 1639 if (!result_saved) {
1659 __ Push(rax); // array literal 1640 PushOperand(rax); // array literal
1660 result_saved = true; 1641 result_saved = true;
1661 } 1642 }
1662 VisitForAccumulatorValue(subexpr); 1643 VisitForAccumulatorValue(subexpr);
1663 1644
1664 __ Move(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); 1645 __ Move(StoreDescriptor::NameRegister(), Smi::FromInt(array_index));
1665 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); 1646 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
1666 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1647 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1667 Handle<Code> ic = 1648 Handle<Code> ic =
1668 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1649 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1669 CallIC(ic); 1650 CallIC(ic);
1670 1651
1671 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1652 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1672 } 1653 }
1673 1654
1674 // In case the array literal contains spread expressions it has two parts. The 1655 // In case the array literal contains spread expressions it has two parts. The
1675 // first part is the "static" array which has a literal index is handled 1656 // first part is the "static" array which has a literal index is handled
1676 // above. The second part is the part after the first spread expression 1657 // above. The second part is the part after the first spread expression
1677 // (inclusive) and these elements gets appended to the array. Note that the 1658 // (inclusive) and these elements gets appended to the array. Note that the
1678 // number elements an iterable produces is unknown ahead of time. 1659 // number elements an iterable produces is unknown ahead of time.
1679 if (array_index < length && result_saved) { 1660 if (array_index < length && result_saved) {
1680 __ Pop(rax); 1661 PopOperand(rax);
1681 result_saved = false; 1662 result_saved = false;
1682 } 1663 }
1683 for (; array_index < length; array_index++) { 1664 for (; array_index < length; array_index++) {
1684 Expression* subexpr = subexprs->at(array_index); 1665 Expression* subexpr = subexprs->at(array_index);
1685 1666
1686 __ Push(rax); 1667 PushOperand(rax);
1687 DCHECK(!subexpr->IsSpread()); 1668 DCHECK(!subexpr->IsSpread());
1688 VisitForStackValue(subexpr); 1669 VisitForStackValue(subexpr);
1689 __ CallRuntime(Runtime::kAppendElement); 1670 CallRuntimeWithOperands(Runtime::kAppendElement);
1690 1671
1691 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1672 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1692 } 1673 }
1693 1674
1694 if (result_saved) { 1675 if (result_saved) {
1695 context()->PlugTOS(); 1676 context()->PlugTOS();
1696 } else { 1677 } else {
1697 context()->Plug(rax); 1678 context()->Plug(rax);
1698 } 1679 }
1699 } 1680 }
(...skipping 20 matching lines...) Expand all
1720 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 1701 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
1721 } else { 1702 } else {
1722 VisitForStackValue(property->obj()); 1703 VisitForStackValue(property->obj());
1723 } 1704 }
1724 break; 1705 break;
1725 case NAMED_SUPER_PROPERTY: 1706 case NAMED_SUPER_PROPERTY:
1726 VisitForStackValue( 1707 VisitForStackValue(
1727 property->obj()->AsSuperPropertyReference()->this_var()); 1708 property->obj()->AsSuperPropertyReference()->this_var());
1728 VisitForAccumulatorValue( 1709 VisitForAccumulatorValue(
1729 property->obj()->AsSuperPropertyReference()->home_object()); 1710 property->obj()->AsSuperPropertyReference()->home_object());
1730 __ Push(result_register()); 1711 PushOperand(result_register());
1731 if (expr->is_compound()) { 1712 if (expr->is_compound()) {
1732 __ Push(MemOperand(rsp, kPointerSize)); 1713 PushOperand(MemOperand(rsp, kPointerSize));
1733 __ Push(result_register()); 1714 PushOperand(result_register());
1734 } 1715 }
1735 break; 1716 break;
1736 case KEYED_SUPER_PROPERTY: 1717 case KEYED_SUPER_PROPERTY:
1737 VisitForStackValue( 1718 VisitForStackValue(
1738 property->obj()->AsSuperPropertyReference()->this_var()); 1719 property->obj()->AsSuperPropertyReference()->this_var());
1739 VisitForStackValue( 1720 VisitForStackValue(
1740 property->obj()->AsSuperPropertyReference()->home_object()); 1721 property->obj()->AsSuperPropertyReference()->home_object());
1741 VisitForAccumulatorValue(property->key()); 1722 VisitForAccumulatorValue(property->key());
1742 __ Push(result_register()); 1723 PushOperand(result_register());
1743 if (expr->is_compound()) { 1724 if (expr->is_compound()) {
1744 __ Push(MemOperand(rsp, 2 * kPointerSize)); 1725 PushOperand(MemOperand(rsp, 2 * kPointerSize));
1745 __ Push(MemOperand(rsp, 2 * kPointerSize)); 1726 PushOperand(MemOperand(rsp, 2 * kPointerSize));
1746 __ Push(result_register()); 1727 PushOperand(result_register());
1747 } 1728 }
1748 break; 1729 break;
1749 case KEYED_PROPERTY: { 1730 case KEYED_PROPERTY: {
1750 if (expr->is_compound()) { 1731 if (expr->is_compound()) {
1751 VisitForStackValue(property->obj()); 1732 VisitForStackValue(property->obj());
1752 VisitForStackValue(property->key()); 1733 VisitForStackValue(property->key());
1753 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); 1734 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize));
1754 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0)); 1735 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0));
1755 } else { 1736 } else {
1756 VisitForStackValue(property->obj()); 1737 VisitForStackValue(property->obj());
(...skipping 25 matching lines...) Expand all
1782 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1763 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1783 break; 1764 break;
1784 case KEYED_PROPERTY: 1765 case KEYED_PROPERTY:
1785 EmitKeyedPropertyLoad(property); 1766 EmitKeyedPropertyLoad(property);
1786 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1767 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1787 break; 1768 break;
1788 } 1769 }
1789 } 1770 }
1790 1771
1791 Token::Value op = expr->binary_op(); 1772 Token::Value op = expr->binary_op();
1792 __ Push(rax); // Left operand goes on the stack. 1773 PushOperand(rax); // Left operand goes on the stack.
1793 VisitForAccumulatorValue(expr->value()); 1774 VisitForAccumulatorValue(expr->value());
1794 1775
1795 AccumulatorValueContext context(this); 1776 AccumulatorValueContext context(this);
1796 if (ShouldInlineSmiCase(op)) { 1777 if (ShouldInlineSmiCase(op)) {
1797 EmitInlineSmiBinaryOp(expr->binary_operation(), 1778 EmitInlineSmiBinaryOp(expr->binary_operation(),
1798 op, 1779 op,
1799 expr->target(), 1780 expr->target(),
1800 expr->value()); 1781 expr->value());
1801 } else { 1782 } else {
1802 EmitBinaryOp(expr->binary_operation(), op); 1783 EmitBinaryOp(expr->binary_operation(), op);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1876 kDontSaveFPRegs); 1857 kDontSaveFPRegs);
1877 __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); 1858 __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset));
1878 __ cmpp(rsp, rbx); 1859 __ cmpp(rsp, rbx);
1879 __ j(equal, &post_runtime); 1860 __ j(equal, &post_runtime);
1880 __ Push(rax); // generator object 1861 __ Push(rax); // generator object
1881 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1862 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1882 __ movp(context_register(), 1863 __ movp(context_register(),
1883 Operand(rbp, StandardFrameConstants::kContextOffset)); 1864 Operand(rbp, StandardFrameConstants::kContextOffset));
1884 __ bind(&post_runtime); 1865 __ bind(&post_runtime);
1885 1866
1886 __ Pop(result_register()); 1867 PopOperand(result_register());
1887 EmitReturnSequence(); 1868 EmitReturnSequence();
1888 1869
1889 __ bind(&resume); 1870 __ bind(&resume);
1890 context()->Plug(result_register()); 1871 context()->Plug(result_register());
1891 break; 1872 break;
1892 } 1873 }
1893 1874
1894 case Yield::kFinal: { 1875 case Yield::kFinal: {
1895 // Pop value from top-of-stack slot, box result into result register. 1876 // Pop value from top-of-stack slot, box result into result register.
1877 OperandStackDepthDecrement(1);
1896 EmitCreateIteratorResult(true); 1878 EmitCreateIteratorResult(true);
1897 EmitUnwindAndReturn(); 1879 EmitUnwindAndReturn();
1898 break; 1880 break;
1899 } 1881 }
1900 1882
1901 case Yield::kDelegating: 1883 case Yield::kDelegating:
1902 UNREACHABLE(); 1884 UNREACHABLE();
1903 } 1885 }
1904 } 1886 }
1905 1887
1906 1888
1907 void FullCodeGenerator::EmitGeneratorResume( 1889 void FullCodeGenerator::EmitGeneratorResume(
1908 Expression* generator, Expression* value, 1890 Expression* generator, Expression* value,
1909 JSGeneratorObject::ResumeMode resume_mode) { 1891 JSGeneratorObject::ResumeMode resume_mode) {
1910 // The value stays in rax, and is ultimately read by the resumed generator, as 1892 // The value stays in rax, and is ultimately read by the resumed generator, as
1911 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1893 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1912 // is read to throw the value when the resumed generator is already closed. 1894 // is read to throw the value when the resumed generator is already closed.
1913 // rbx will hold the generator object until the activation has been resumed. 1895 // rbx will hold the generator object until the activation has been resumed.
1914 VisitForStackValue(generator); 1896 VisitForStackValue(generator);
1915 VisitForAccumulatorValue(value); 1897 VisitForAccumulatorValue(value);
1916 __ Pop(rbx); 1898 PopOperand(rbx);
1917 1899
1918 // Store input value into generator object. 1900 // Store input value into generator object.
1919 __ movp(FieldOperand(rbx, JSGeneratorObject::kInputOffset), 1901 __ movp(FieldOperand(rbx, JSGeneratorObject::kInputOffset),
1920 result_register()); 1902 result_register());
1921 __ movp(rcx, result_register()); 1903 __ movp(rcx, result_register());
1922 __ RecordWriteField(rbx, JSGeneratorObject::kInputOffset, rcx, rdx, 1904 __ RecordWriteField(rbx, JSGeneratorObject::kInputOffset, rcx, rdx,
1923 kDontSaveFPRegs); 1905 kDontSaveFPRegs);
1924 1906
1925 // Load suspended function and context. 1907 // Load suspended function and context.
1926 __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); 1908 __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset));
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 __ Push(result_register()); 1971 __ Push(result_register());
1990 __ Push(Smi::FromInt(resume_mode)); 1972 __ Push(Smi::FromInt(resume_mode));
1991 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 1973 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
1992 // Not reached: the runtime call returns elsewhere. 1974 // Not reached: the runtime call returns elsewhere.
1993 __ Abort(kGeneratorFailedToResume); 1975 __ Abort(kGeneratorFailedToResume);
1994 1976
1995 __ bind(&done); 1977 __ bind(&done);
1996 context()->Plug(result_register()); 1978 context()->Plug(result_register());
1997 } 1979 }
1998 1980
1981 void FullCodeGenerator::PushOperand(MemOperand operand) {
1982 OperandStackDepthIncrement(1);
1983 __ Push(operand);
1984 }
1985
1986 void FullCodeGenerator::EmitOperandStackDepthCheck() {
1987 if (FLAG_debug_code) {
1988 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
1989 operand_stack_depth_ * kPointerSize;
1990 __ movp(rax, rbp);
1991 __ subp(rax, rsp);
1992 __ cmpp(rax, Immediate(expected_diff));
1993 __ Assert(equal, kUnexpectedStackDepth);
1994 }
1995 }
1999 1996
2000 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 1997 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2001 Label allocate, done_allocate; 1998 Label allocate, done_allocate;
2002 1999
2003 __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &allocate, TAG_OBJECT); 2000 __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &allocate, TAG_OBJECT);
2004 __ jmp(&done_allocate, Label::kNear); 2001 __ jmp(&done_allocate, Label::kNear);
2005 2002
2006 __ bind(&allocate); 2003 __ bind(&allocate);
2007 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2004 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2008 __ CallRuntime(Runtime::kAllocateInNewSpace); 2005 __ CallRuntime(Runtime::kAllocateInNewSpace);
2009 2006
2010 __ bind(&done_allocate); 2007 __ bind(&done_allocate);
2011 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, rbx); 2008 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, rbx);
2012 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); 2009 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx);
2013 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); 2010 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
2014 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); 2011 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
2015 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); 2012 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx);
2016 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); 2013 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset));
2017 __ LoadRoot(FieldOperand(rax, JSIteratorResult::kDoneOffset), 2014 __ LoadRoot(FieldOperand(rax, JSIteratorResult::kDoneOffset),
2018 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); 2015 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
2019 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 2016 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
2020 } 2017 }
2021 2018
2022 2019
2023 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2020 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2024 SetExpressionPosition(prop); 2021 SetExpressionPosition(prop);
2025 Literal* key = prop->key()->AsLiteral(); 2022 Literal* key = prop->key()->AsLiteral();
2023 DCHECK(!key->value()->IsSmi());
2026 DCHECK(!prop->IsSuperAccess()); 2024 DCHECK(!prop->IsSuperAccess());
2027 2025
2028 __ Move(LoadDescriptor::NameRegister(), key->value()); 2026 __ Move(LoadDescriptor::NameRegister(), key->value());
2029 __ Move(LoadDescriptor::SlotRegister(), 2027 __ Move(LoadDescriptor::SlotRegister(),
2030 SmiFromSlot(prop->PropertyFeedbackSlot())); 2028 SmiFromSlot(prop->PropertyFeedbackSlot()));
2031 CallLoadIC(NOT_INSIDE_TYPEOF); 2029 CallLoadIC(NOT_INSIDE_TYPEOF);
2032 } 2030 }
2033 2031
2034 2032
2035 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2036 // Stack: receiver, home_object
2037 SetExpressionPosition(prop);
2038 Literal* key = prop->key()->AsLiteral();
2039 DCHECK(!key->value()->IsSmi());
2040 DCHECK(prop->IsSuperAccess());
2041
2042 __ Push(key->value());
2043 __ CallRuntime(Runtime::kLoadFromSuper);
2044 }
2045
2046
2047 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2048 SetExpressionPosition(prop);
2049 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2050 __ Move(LoadDescriptor::SlotRegister(),
2051 SmiFromSlot(prop->PropertyFeedbackSlot()));
2052 CallIC(ic);
2053 }
2054
2055
2056 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2057 // Stack: receiver, home_object, key.
2058 SetExpressionPosition(prop);
2059 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2060 }
2061
2062
2063 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2033 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2064 Token::Value op, 2034 Token::Value op,
2065 Expression* left, 2035 Expression* left,
2066 Expression* right) { 2036 Expression* right) {
2067 // Do combined smi check of the operands. Left operand is on the 2037 // Do combined smi check of the operands. Left operand is on the
2068 // stack (popped into rdx). Right operand is in rax but moved into 2038 // stack (popped into rdx). Right operand is in rax but moved into
2069 // rcx to make the shifts easier. 2039 // rcx to make the shifts easier.
2070 Label done, stub_call, smi_case; 2040 Label done, stub_call, smi_case;
2071 __ Pop(rdx); 2041 PopOperand(rdx);
2072 __ movp(rcx, rax); 2042 __ movp(rcx, rax);
2073 __ orp(rax, rdx); 2043 __ orp(rax, rdx);
2074 JumpPatchSite patch_site(masm_); 2044 JumpPatchSite patch_site(masm_);
2075 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); 2045 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear);
2076 2046
2077 __ bind(&stub_call); 2047 __ bind(&stub_call);
2078 __ movp(rax, rcx); 2048 __ movp(rax, rcx);
2079 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2049 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2080 CallIC(code, expr->BinaryOperationFeedbackId()); 2050 CallIC(code, expr->BinaryOperationFeedbackId());
2081 patch_site.EmitPatchInfo(); 2051 patch_site.EmitPatchInfo();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 context()->Plug(rax); 2089 context()->Plug(rax);
2120 } 2090 }
2121 2091
2122 2092
2123 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { 2093 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
2124 for (int i = 0; i < lit->properties()->length(); i++) { 2094 for (int i = 0; i < lit->properties()->length(); i++) {
2125 ObjectLiteral::Property* property = lit->properties()->at(i); 2095 ObjectLiteral::Property* property = lit->properties()->at(i);
2126 Expression* value = property->value(); 2096 Expression* value = property->value();
2127 2097
2128 if (property->is_static()) { 2098 if (property->is_static()) {
2129 __ Push(Operand(rsp, kPointerSize)); // constructor 2099 PushOperand(Operand(rsp, kPointerSize)); // constructor
2130 } else { 2100 } else {
2131 __ Push(Operand(rsp, 0)); // prototype 2101 PushOperand(Operand(rsp, 0)); // prototype
2132 } 2102 }
2133 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2103 EmitPropertyKey(property, lit->GetIdForProperty(i));
2134 2104
2135 // The static prototype property is read only. We handle the non computed 2105 // The static prototype property is read only. We handle the non computed
2136 // property name case in the parser. Since this is the only case where we 2106 // property name case in the parser. Since this is the only case where we
2137 // need to check for an own read only property we special case this so we do 2107 // need to check for an own read only property we special case this so we do
2138 // not need to do this for every property. 2108 // not need to do this for every property.
2139 if (property->is_static() && property->is_computed_name()) { 2109 if (property->is_static() && property->is_computed_name()) {
2140 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2110 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2141 __ Push(rax); 2111 __ Push(rax);
2142 } 2112 }
2143 2113
2144 VisitForStackValue(value); 2114 VisitForStackValue(value);
2145 if (NeedsHomeObject(value)) { 2115 if (NeedsHomeObject(value)) {
2146 EmitSetHomeObject(value, 2, property->GetSlot()); 2116 EmitSetHomeObject(value, 2, property->GetSlot());
2147 } 2117 }
2148 2118
2149 switch (property->kind()) { 2119 switch (property->kind()) {
2150 case ObjectLiteral::Property::CONSTANT: 2120 case ObjectLiteral::Property::CONSTANT:
2151 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2121 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2152 case ObjectLiteral::Property::PROTOTYPE: 2122 case ObjectLiteral::Property::PROTOTYPE:
2153 UNREACHABLE(); 2123 UNREACHABLE();
2154 case ObjectLiteral::Property::COMPUTED: 2124 case ObjectLiteral::Property::COMPUTED:
2155 __ Push(Smi::FromInt(DONT_ENUM)); 2125 PushOperand(Smi::FromInt(DONT_ENUM));
2156 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2126 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2157 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2127 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2158 break; 2128 break;
2159 2129
2160 case ObjectLiteral::Property::GETTER: 2130 case ObjectLiteral::Property::GETTER:
2161 __ Push(Smi::FromInt(DONT_ENUM)); 2131 PushOperand(Smi::FromInt(DONT_ENUM));
2162 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2132 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2163 break; 2133 break;
2164 2134
2165 case ObjectLiteral::Property::SETTER: 2135 case ObjectLiteral::Property::SETTER:
2166 __ Push(Smi::FromInt(DONT_ENUM)); 2136 PushOperand(Smi::FromInt(DONT_ENUM));
2167 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2137 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2168 break; 2138 break;
2169 2139
2170 default: 2140 default:
2171 UNREACHABLE(); 2141 UNREACHABLE();
2172 } 2142 }
2173 } 2143 }
2174 } 2144 }
2175 2145
2176 2146
2177 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2147 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2178 __ Pop(rdx); 2148 PopOperand(rdx);
2179 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2149 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2180 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2150 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2181 CallIC(code, expr->BinaryOperationFeedbackId()); 2151 CallIC(code, expr->BinaryOperationFeedbackId());
2182 patch_site.EmitPatchInfo(); 2152 patch_site.EmitPatchInfo();
2183 context()->Plug(rax); 2153 context()->Plug(rax);
2184 } 2154 }
2185 2155
2186 2156
2187 void FullCodeGenerator::EmitAssignment(Expression* expr, 2157 void FullCodeGenerator::EmitAssignment(Expression* expr,
2188 FeedbackVectorSlot slot) { 2158 FeedbackVectorSlot slot) {
2189 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2159 DCHECK(expr->IsValidReferenceExpressionOrThis());
2190 2160
2191 Property* prop = expr->AsProperty(); 2161 Property* prop = expr->AsProperty();
2192 LhsKind assign_type = Property::GetAssignType(prop); 2162 LhsKind assign_type = Property::GetAssignType(prop);
2193 2163
2194 switch (assign_type) { 2164 switch (assign_type) {
2195 case VARIABLE: { 2165 case VARIABLE: {
2196 Variable* var = expr->AsVariableProxy()->var(); 2166 Variable* var = expr->AsVariableProxy()->var();
2197 EffectContext context(this); 2167 EffectContext context(this);
2198 EmitVariableAssignment(var, Token::ASSIGN, slot); 2168 EmitVariableAssignment(var, Token::ASSIGN, slot);
2199 break; 2169 break;
2200 } 2170 }
2201 case NAMED_PROPERTY: { 2171 case NAMED_PROPERTY: {
2202 __ Push(rax); // Preserve value. 2172 PushOperand(rax); // Preserve value.
2203 VisitForAccumulatorValue(prop->obj()); 2173 VisitForAccumulatorValue(prop->obj());
2204 __ Move(StoreDescriptor::ReceiverRegister(), rax); 2174 __ Move(StoreDescriptor::ReceiverRegister(), rax);
2205 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. 2175 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2206 __ Move(StoreDescriptor::NameRegister(), 2176 __ Move(StoreDescriptor::NameRegister(),
2207 prop->key()->AsLiteral()->value()); 2177 prop->key()->AsLiteral()->value());
2208 EmitLoadStoreICSlot(slot); 2178 EmitLoadStoreICSlot(slot);
2209 CallStoreIC(); 2179 CallStoreIC();
2210 break; 2180 break;
2211 } 2181 }
2212 case NAMED_SUPER_PROPERTY: { 2182 case NAMED_SUPER_PROPERTY: {
2213 __ Push(rax); 2183 PushOperand(rax);
2214 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2184 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2215 VisitForAccumulatorValue( 2185 VisitForAccumulatorValue(
2216 prop->obj()->AsSuperPropertyReference()->home_object()); 2186 prop->obj()->AsSuperPropertyReference()->home_object());
2217 // stack: value, this; rax: home_object 2187 // stack: value, this; rax: home_object
2218 Register scratch = rcx; 2188 Register scratch = rcx;
2219 Register scratch2 = rdx; 2189 Register scratch2 = rdx;
2220 __ Move(scratch, result_register()); // home_object 2190 __ Move(scratch, result_register()); // home_object
2221 __ movp(rax, MemOperand(rsp, kPointerSize)); // value 2191 __ movp(rax, MemOperand(rsp, kPointerSize)); // value
2222 __ movp(scratch2, MemOperand(rsp, 0)); // this 2192 __ movp(scratch2, MemOperand(rsp, 0)); // this
2223 __ movp(MemOperand(rsp, kPointerSize), scratch2); // this 2193 __ movp(MemOperand(rsp, kPointerSize), scratch2); // this
2224 __ movp(MemOperand(rsp, 0), scratch); // home_object 2194 __ movp(MemOperand(rsp, 0), scratch); // home_object
2225 // stack: this, home_object; rax: value 2195 // stack: this, home_object; rax: value
2226 EmitNamedSuperPropertyStore(prop); 2196 EmitNamedSuperPropertyStore(prop);
2227 break; 2197 break;
2228 } 2198 }
2229 case KEYED_SUPER_PROPERTY: { 2199 case KEYED_SUPER_PROPERTY: {
2230 __ Push(rax); 2200 PushOperand(rax);
2231 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2201 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2232 VisitForStackValue( 2202 VisitForStackValue(
2233 prop->obj()->AsSuperPropertyReference()->home_object()); 2203 prop->obj()->AsSuperPropertyReference()->home_object());
2234 VisitForAccumulatorValue(prop->key()); 2204 VisitForAccumulatorValue(prop->key());
2235 Register scratch = rcx; 2205 Register scratch = rcx;
2236 Register scratch2 = rdx; 2206 Register scratch2 = rdx;
2237 __ movp(scratch2, MemOperand(rsp, 2 * kPointerSize)); // value 2207 __ movp(scratch2, MemOperand(rsp, 2 * kPointerSize)); // value
2238 // stack: value, this, home_object; rax: key, rdx: value 2208 // stack: value, this, home_object; rax: key, rdx: value
2239 __ movp(scratch, MemOperand(rsp, kPointerSize)); // this 2209 __ movp(scratch, MemOperand(rsp, kPointerSize)); // this
2240 __ movp(MemOperand(rsp, 2 * kPointerSize), scratch); 2210 __ movp(MemOperand(rsp, 2 * kPointerSize), scratch);
2241 __ movp(scratch, MemOperand(rsp, 0)); // home_object 2211 __ movp(scratch, MemOperand(rsp, 0)); // home_object
2242 __ movp(MemOperand(rsp, kPointerSize), scratch); 2212 __ movp(MemOperand(rsp, kPointerSize), scratch);
2243 __ movp(MemOperand(rsp, 0), rax); 2213 __ movp(MemOperand(rsp, 0), rax);
2244 __ Move(rax, scratch2); 2214 __ Move(rax, scratch2);
2245 // stack: this, home_object, key; rax: value. 2215 // stack: this, home_object, key; rax: value.
2246 EmitKeyedSuperPropertyStore(prop); 2216 EmitKeyedSuperPropertyStore(prop);
2247 break; 2217 break;
2248 } 2218 }
2249 case KEYED_PROPERTY: { 2219 case KEYED_PROPERTY: {
2250 __ Push(rax); // Preserve value. 2220 PushOperand(rax); // Preserve value.
2251 VisitForStackValue(prop->obj()); 2221 VisitForStackValue(prop->obj());
2252 VisitForAccumulatorValue(prop->key()); 2222 VisitForAccumulatorValue(prop->key());
2253 __ Move(StoreDescriptor::NameRegister(), rax); 2223 __ Move(StoreDescriptor::NameRegister(), rax);
2254 __ Pop(StoreDescriptor::ReceiverRegister()); 2224 PopOperand(StoreDescriptor::ReceiverRegister());
2255 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. 2225 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2256 EmitLoadStoreICSlot(slot); 2226 EmitLoadStoreICSlot(slot);
2257 Handle<Code> ic = 2227 Handle<Code> ic =
2258 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2228 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2259 CallIC(ic); 2229 CallIC(ic);
2260 break; 2230 break;
2261 } 2231 }
2262 } 2232 }
2263 context()->Plug(rax); 2233 context()->Plug(rax);
2264 } 2234 }
2265 2235
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 } 2347 }
2378 2348
2379 2349
2380 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2350 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2381 // Assignment to a property, using a named store IC. 2351 // Assignment to a property, using a named store IC.
2382 Property* prop = expr->target()->AsProperty(); 2352 Property* prop = expr->target()->AsProperty();
2383 DCHECK(prop != NULL); 2353 DCHECK(prop != NULL);
2384 DCHECK(prop->key()->IsLiteral()); 2354 DCHECK(prop->key()->IsLiteral());
2385 2355
2386 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 2356 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2387 __ Pop(StoreDescriptor::ReceiverRegister()); 2357 PopOperand(StoreDescriptor::ReceiverRegister());
2388 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2358 EmitLoadStoreICSlot(expr->AssignmentSlot());
2389 CallStoreIC(); 2359 CallStoreIC();
2390 2360
2391 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2361 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2392 context()->Plug(rax); 2362 context()->Plug(rax);
2393 } 2363 }
2394 2364
2395 2365
2396 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2366 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2397 // Assignment to named property of super. 2367 // Assignment to named property of super.
2398 // rax : value 2368 // rax : value
2399 // stack : receiver ('this'), home_object 2369 // stack : receiver ('this'), home_object
2400 DCHECK(prop != NULL); 2370 DCHECK(prop != NULL);
2401 Literal* key = prop->key()->AsLiteral(); 2371 Literal* key = prop->key()->AsLiteral();
2402 DCHECK(key != NULL); 2372 DCHECK(key != NULL);
2403 2373
2404 __ Push(key->value()); 2374 PushOperand(key->value());
2405 __ Push(rax); 2375 PushOperand(rax);
2406 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2376 CallRuntimeWithOperands(is_strict(language_mode())
2407 : Runtime::kStoreToSuper_Sloppy)); 2377 ? Runtime::kStoreToSuper_Strict
2378 : Runtime::kStoreToSuper_Sloppy);
2408 } 2379 }
2409 2380
2410 2381
2411 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2382 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2412 // Assignment to named property of super. 2383 // Assignment to named property of super.
2413 // rax : value 2384 // rax : value
2414 // stack : receiver ('this'), home_object, key 2385 // stack : receiver ('this'), home_object, key
2415 DCHECK(prop != NULL); 2386 DCHECK(prop != NULL);
2416 2387
2417 __ Push(rax); 2388 PushOperand(rax);
2418 __ CallRuntime((is_strict(language_mode()) 2389 CallRuntimeWithOperands(is_strict(language_mode())
2419 ? Runtime::kStoreKeyedToSuper_Strict 2390 ? Runtime::kStoreKeyedToSuper_Strict
2420 : Runtime::kStoreKeyedToSuper_Sloppy)); 2391 : Runtime::kStoreKeyedToSuper_Sloppy);
2421 } 2392 }
2422 2393
2423 2394
2424 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2395 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2425 // Assignment to a property, using a keyed store IC. 2396 // Assignment to a property, using a keyed store IC.
2426 __ Pop(StoreDescriptor::NameRegister()); // Key. 2397 PopOperand(StoreDescriptor::NameRegister()); // Key.
2427 __ Pop(StoreDescriptor::ReceiverRegister()); 2398 PopOperand(StoreDescriptor::ReceiverRegister());
2428 DCHECK(StoreDescriptor::ValueRegister().is(rax)); 2399 DCHECK(StoreDescriptor::ValueRegister().is(rax));
2429 Handle<Code> ic = 2400 Handle<Code> ic =
2430 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2401 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2431 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2402 EmitLoadStoreICSlot(expr->AssignmentSlot());
2432 CallIC(ic); 2403 CallIC(ic);
2433 2404
2434 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2405 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2435 context()->Plug(rax); 2406 context()->Plug(rax);
2436 } 2407 }
2437 2408
(...skipping 14 matching lines...) Expand all
2452 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2423 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2453 VisitForStackValue( 2424 VisitForStackValue(
2454 expr->obj()->AsSuperPropertyReference()->home_object()); 2425 expr->obj()->AsSuperPropertyReference()->home_object());
2455 EmitNamedSuperPropertyLoad(expr); 2426 EmitNamedSuperPropertyLoad(expr);
2456 } 2427 }
2457 } else { 2428 } else {
2458 if (!expr->IsSuperAccess()) { 2429 if (!expr->IsSuperAccess()) {
2459 VisitForStackValue(expr->obj()); 2430 VisitForStackValue(expr->obj());
2460 VisitForAccumulatorValue(expr->key()); 2431 VisitForAccumulatorValue(expr->key());
2461 __ Move(LoadDescriptor::NameRegister(), rax); 2432 __ Move(LoadDescriptor::NameRegister(), rax);
2462 __ Pop(LoadDescriptor::ReceiverRegister()); 2433 PopOperand(LoadDescriptor::ReceiverRegister());
2463 EmitKeyedPropertyLoad(expr); 2434 EmitKeyedPropertyLoad(expr);
2464 } else { 2435 } else {
2465 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2436 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2466 VisitForStackValue( 2437 VisitForStackValue(
2467 expr->obj()->AsSuperPropertyReference()->home_object()); 2438 expr->obj()->AsSuperPropertyReference()->home_object());
2468 VisitForStackValue(expr->key()); 2439 VisitForStackValue(expr->key());
2469 EmitKeyedSuperPropertyLoad(expr); 2440 EmitKeyedSuperPropertyLoad(expr);
2470 } 2441 }
2471 } 2442 }
2472 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2443 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
(...skipping 14 matching lines...) Expand all
2487 2458
2488 // Get the target function. 2459 // Get the target function.
2489 ConvertReceiverMode convert_mode; 2460 ConvertReceiverMode convert_mode;
2490 if (callee->IsVariableProxy()) { 2461 if (callee->IsVariableProxy()) {
2491 { StackValueContext context(this); 2462 { StackValueContext context(this);
2492 EmitVariableLoad(callee->AsVariableProxy()); 2463 EmitVariableLoad(callee->AsVariableProxy());
2493 PrepareForBailout(callee, NO_REGISTERS); 2464 PrepareForBailout(callee, NO_REGISTERS);
2494 } 2465 }
2495 // Push undefined as receiver. This is patched in the Call builtin if it 2466 // Push undefined as receiver. This is patched in the Call builtin if it
2496 // is a sloppy mode method. 2467 // is a sloppy mode method.
2497 __ Push(isolate()->factory()->undefined_value()); 2468 PushOperand(isolate()->factory()->undefined_value());
2498 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2469 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2499 } else { 2470 } else {
2500 // Load the function from the receiver. 2471 // Load the function from the receiver.
2501 DCHECK(callee->IsProperty()); 2472 DCHECK(callee->IsProperty());
2502 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2473 DCHECK(!callee->AsProperty()->IsSuperAccess());
2503 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 2474 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
2504 EmitNamedPropertyLoad(callee->AsProperty()); 2475 EmitNamedPropertyLoad(callee->AsProperty());
2505 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2476 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2506 // Push the target function under the receiver. 2477 // Push the target function under the receiver.
2507 __ Push(Operand(rsp, 0)); 2478 PushOperand(Operand(rsp, 0));
2508 __ movp(Operand(rsp, kPointerSize), rax); 2479 __ movp(Operand(rsp, kPointerSize), rax);
2509 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2480 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2510 } 2481 }
2511 2482
2512 EmitCall(expr, convert_mode); 2483 EmitCall(expr, convert_mode);
2513 } 2484 }
2514 2485
2515 2486
2516 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2487 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2517 Expression* callee = expr->expression(); 2488 Expression* callee = expr->expression();
2518 DCHECK(callee->IsProperty()); 2489 DCHECK(callee->IsProperty());
2519 Property* prop = callee->AsProperty(); 2490 Property* prop = callee->AsProperty();
2520 DCHECK(prop->IsSuperAccess()); 2491 DCHECK(prop->IsSuperAccess());
2521 SetExpressionPosition(prop); 2492 SetExpressionPosition(prop);
2522 2493
2523 Literal* key = prop->key()->AsLiteral(); 2494 Literal* key = prop->key()->AsLiteral();
2524 DCHECK(!key->value()->IsSmi()); 2495 DCHECK(!key->value()->IsSmi());
2525 // Load the function from the receiver. 2496 // Load the function from the receiver.
2526 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2497 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2527 VisitForStackValue(super_ref->home_object()); 2498 VisitForStackValue(super_ref->home_object());
2528 VisitForAccumulatorValue(super_ref->this_var()); 2499 VisitForAccumulatorValue(super_ref->this_var());
2529 __ Push(rax); 2500 PushOperand(rax);
2530 __ Push(rax); 2501 PushOperand(rax);
2531 __ Push(Operand(rsp, kPointerSize * 2)); 2502 PushOperand(Operand(rsp, kPointerSize * 2));
2532 __ Push(key->value()); 2503 PushOperand(key->value());
2533 2504
2534 // Stack here: 2505 // Stack here:
2535 // - home_object 2506 // - home_object
2536 // - this (receiver) 2507 // - this (receiver)
2537 // - this (receiver) <-- LoadFromSuper will pop here and below. 2508 // - this (receiver) <-- LoadFromSuper will pop here and below.
2538 // - home_object 2509 // - home_object
2539 // - key 2510 // - key
2540 __ CallRuntime(Runtime::kLoadFromSuper); 2511 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2541 2512
2542 // Replace home_object with target function. 2513 // Replace home_object with target function.
2543 __ movp(Operand(rsp, kPointerSize), rax); 2514 __ movp(Operand(rsp, kPointerSize), rax);
2544 2515
2545 // Stack here: 2516 // Stack here:
2546 // - target function 2517 // - target function
2547 // - this (receiver) 2518 // - this (receiver)
2548 EmitCall(expr); 2519 EmitCall(expr);
2549 } 2520 }
2550 2521
2551 2522
2552 // Common code for calls using the IC. 2523 // Common code for calls using the IC.
2553 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2524 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2554 Expression* key) { 2525 Expression* key) {
2555 // Load the key. 2526 // Load the key.
2556 VisitForAccumulatorValue(key); 2527 VisitForAccumulatorValue(key);
2557 2528
2558 Expression* callee = expr->expression(); 2529 Expression* callee = expr->expression();
2559 2530
2560 // Load the function from the receiver. 2531 // Load the function from the receiver.
2561 DCHECK(callee->IsProperty()); 2532 DCHECK(callee->IsProperty());
2562 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 2533 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
2563 __ Move(LoadDescriptor::NameRegister(), rax); 2534 __ Move(LoadDescriptor::NameRegister(), rax);
2564 EmitKeyedPropertyLoad(callee->AsProperty()); 2535 EmitKeyedPropertyLoad(callee->AsProperty());
2565 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2536 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2566 2537
2567 // Push the target function under the receiver. 2538 // Push the target function under the receiver.
2568 __ Push(Operand(rsp, 0)); 2539 PushOperand(Operand(rsp, 0));
2569 __ movp(Operand(rsp, kPointerSize), rax); 2540 __ movp(Operand(rsp, kPointerSize), rax);
2570 2541
2571 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2542 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2572 } 2543 }
2573 2544
2574 2545
2575 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2546 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2576 Expression* callee = expr->expression(); 2547 Expression* callee = expr->expression();
2577 DCHECK(callee->IsProperty()); 2548 DCHECK(callee->IsProperty());
2578 Property* prop = callee->AsProperty(); 2549 Property* prop = callee->AsProperty();
2579 DCHECK(prop->IsSuperAccess()); 2550 DCHECK(prop->IsSuperAccess());
2580 2551
2581 SetExpressionPosition(prop); 2552 SetExpressionPosition(prop);
2582 // Load the function from the receiver. 2553 // Load the function from the receiver.
2583 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2554 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2584 VisitForStackValue(super_ref->home_object()); 2555 VisitForStackValue(super_ref->home_object());
2585 VisitForAccumulatorValue(super_ref->this_var()); 2556 VisitForAccumulatorValue(super_ref->this_var());
2586 __ Push(rax); 2557 PushOperand(rax);
2587 __ Push(rax); 2558 PushOperand(rax);
2588 __ Push(Operand(rsp, kPointerSize * 2)); 2559 PushOperand(Operand(rsp, kPointerSize * 2));
2589 VisitForStackValue(prop->key()); 2560 VisitForStackValue(prop->key());
2590 2561
2591 // Stack here: 2562 // Stack here:
2592 // - home_object 2563 // - home_object
2593 // - this (receiver) 2564 // - this (receiver)
2594 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2565 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2595 // - home_object 2566 // - home_object
2596 // - key 2567 // - key
2597 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2568 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2598 2569
2599 // Replace home_object with target function. 2570 // Replace home_object with target function.
2600 __ movp(Operand(rsp, kPointerSize), rax); 2571 __ movp(Operand(rsp, kPointerSize), rax);
2601 2572
2602 // Stack here: 2573 // Stack here:
2603 // - target function 2574 // - target function
2604 // - this (receiver) 2575 // - this (receiver)
2605 EmitCall(expr); 2576 EmitCall(expr);
2606 } 2577 }
2607 2578
(...skipping 17 matching lines...) Expand all
2625 EmitProfilingCounterHandlingForReturnSequence(true); 2596 EmitProfilingCounterHandlingForReturnSequence(true);
2626 } 2597 }
2627 Handle<Code> ic = 2598 Handle<Code> ic =
2628 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2599 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2629 .code(); 2600 .code();
2630 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); 2601 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot()));
2631 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 2602 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
2632 // Don't assign a type feedback id to the IC, since type feedback is provided 2603 // Don't assign a type feedback id to the IC, since type feedback is provided
2633 // by the vector above. 2604 // by the vector above.
2634 CallIC(ic); 2605 CallIC(ic);
2606 OperandStackDepthDecrement(arg_count + 1);
2635 2607
2636 RecordJSReturnSite(expr); 2608 RecordJSReturnSite(expr);
2637 2609
2638 // Restore context register. 2610 // Restore context register.
2639 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2611 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2640 // Discard the function left on TOS. 2612 // Discard the function left on TOS.
2641 context()->DropAndPlug(1, rax); 2613 context()->DropAndPlug(1, rax);
2642 } 2614 }
2643 2615
2644 2616
(...skipping 26 matching lines...) Expand all
2671 Label slow, done; 2643 Label slow, done;
2672 SetExpressionPosition(callee); 2644 SetExpressionPosition(callee);
2673 // Generate code for loading from variables potentially shadowed by 2645 // Generate code for loading from variables potentially shadowed by
2674 // eval-introduced variables. 2646 // eval-introduced variables.
2675 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2647 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2676 __ bind(&slow); 2648 __ bind(&slow);
2677 // Call the runtime to find the function to call (returned in rax) and 2649 // Call the runtime to find the function to call (returned in rax) and
2678 // the object holding it (returned in rdx). 2650 // the object holding it (returned in rdx).
2679 __ Push(callee->name()); 2651 __ Push(callee->name());
2680 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2652 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2681 __ Push(rax); // Function. 2653 PushOperand(rax); // Function.
2682 __ Push(rdx); // Receiver. 2654 PushOperand(rdx); // Receiver.
2683 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2655 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2684 2656
2685 // If fast case code has been generated, emit code to push the function 2657 // If fast case code has been generated, emit code to push the function
2686 // and receiver and have the slow path jump around this code. 2658 // and receiver and have the slow path jump around this code.
2687 if (done.is_linked()) { 2659 if (done.is_linked()) {
2688 Label call; 2660 Label call;
2689 __ jmp(&call, Label::kNear); 2661 __ jmp(&call, Label::kNear);
2690 __ bind(&done); 2662 __ bind(&done);
2691 // Push function. 2663 // Push function.
2692 __ Push(rax); 2664 __ Push(rax);
2693 // Pass undefined as the receiver, which is the WithBaseObject of a 2665 // Pass undefined as the receiver, which is the WithBaseObject of a
2694 // non-object environment record. If the callee is sloppy, it will patch 2666 // non-object environment record. If the callee is sloppy, it will patch
2695 // it up to be the global receiver. 2667 // it up to be the global receiver.
2696 __ PushRoot(Heap::kUndefinedValueRootIndex); 2668 __ PushRoot(Heap::kUndefinedValueRootIndex);
2697 __ bind(&call); 2669 __ bind(&call);
2698 } 2670 }
2699 } else { 2671 } else {
2700 VisitForStackValue(callee); 2672 VisitForStackValue(callee);
2701 // refEnv.WithBaseObject() 2673 // refEnv.WithBaseObject()
2674 OperandStackDepthIncrement(1);
2702 __ PushRoot(Heap::kUndefinedValueRootIndex); 2675 __ PushRoot(Heap::kUndefinedValueRootIndex);
2703 } 2676 }
2704 } 2677 }
2705 2678
2706 2679
2707 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2680 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2708 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2681 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2709 // to resolve the function we need to call. Then we call the resolved 2682 // to resolve the function we need to call. Then we call the resolved
2710 // function using the given arguments. 2683 // function using the given arguments.
2711 ZoneList<Expression*>* args = expr->arguments(); 2684 ZoneList<Expression*>* args = expr->arguments();
(...skipping 14 matching lines...) Expand all
2726 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); 2699 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
2727 2700
2728 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2701 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2729 2702
2730 SetCallPosition(expr); 2703 SetCallPosition(expr);
2731 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 2704 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
2732 __ Set(rax, arg_count); 2705 __ Set(rax, arg_count);
2733 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2706 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2734 expr->tail_call_mode()), 2707 expr->tail_call_mode()),
2735 RelocInfo::CODE_TARGET); 2708 RelocInfo::CODE_TARGET);
2709 OperandStackDepthDecrement(arg_count + 1);
2736 RecordJSReturnSite(expr); 2710 RecordJSReturnSite(expr);
2737 // Restore context register. 2711 // Restore context register.
2738 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2712 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2739 context()->DropAndPlug(1, rax); 2713 context()->DropAndPlug(1, rax);
2740 } 2714 }
2741 2715
2742 2716
2743 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2717 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2744 Comment cmnt(masm_, "[ CallNew"); 2718 Comment cmnt(masm_, "[ CallNew");
2745 // According to ECMA-262, section 11.2.2, page 44, the function 2719 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2766 // Load function and argument count into rdi and rax. 2740 // Load function and argument count into rdi and rax.
2767 __ Set(rax, arg_count); 2741 __ Set(rax, arg_count);
2768 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); 2742 __ movp(rdi, Operand(rsp, arg_count * kPointerSize));
2769 2743
2770 // Record call targets in unoptimized code, but not in the snapshot. 2744 // Record call targets in unoptimized code, but not in the snapshot.
2771 __ EmitLoadTypeFeedbackVector(rbx); 2745 __ EmitLoadTypeFeedbackVector(rbx);
2772 __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot())); 2746 __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot()));
2773 2747
2774 CallConstructStub stub(isolate()); 2748 CallConstructStub stub(isolate());
2775 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2749 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2750 OperandStackDepthDecrement(arg_count + 1);
2776 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2751 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2777 // Restore context register. 2752 // Restore context register.
2778 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2753 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2779 context()->Plug(rax); 2754 context()->Plug(rax);
2780 } 2755 }
2781 2756
2782 2757
2783 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2758 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2784 SuperCallReference* super_call_ref = 2759 SuperCallReference* super_call_ref =
2785 expr->expression()->AsSuperCallReference(); 2760 expr->expression()->AsSuperCallReference();
2786 DCHECK_NOT_NULL(super_call_ref); 2761 DCHECK_NOT_NULL(super_call_ref);
2787 2762
2788 // Push the super constructor target on the stack (may be null, 2763 // Push the super constructor target on the stack (may be null,
2789 // but the Construct builtin can deal with that properly). 2764 // but the Construct builtin can deal with that properly).
2790 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2765 VisitForAccumulatorValue(super_call_ref->this_function_var());
2791 __ AssertFunction(result_register()); 2766 __ AssertFunction(result_register());
2792 __ movp(result_register(), 2767 __ movp(result_register(),
2793 FieldOperand(result_register(), HeapObject::kMapOffset)); 2768 FieldOperand(result_register(), HeapObject::kMapOffset));
2794 __ Push(FieldOperand(result_register(), Map::kPrototypeOffset)); 2769 PushOperand(FieldOperand(result_register(), Map::kPrototypeOffset));
2795 2770
2796 // Push the arguments ("left-to-right") on the stack. 2771 // Push the arguments ("left-to-right") on the stack.
2797 ZoneList<Expression*>* args = expr->arguments(); 2772 ZoneList<Expression*>* args = expr->arguments();
2798 int arg_count = args->length(); 2773 int arg_count = args->length();
2799 for (int i = 0; i < arg_count; i++) { 2774 for (int i = 0; i < arg_count; i++) {
2800 VisitForStackValue(args->at(i)); 2775 VisitForStackValue(args->at(i));
2801 } 2776 }
2802 2777
2803 // Call the construct call builtin that handles allocation and 2778 // Call the construct call builtin that handles allocation and
2804 // constructor invocation. 2779 // constructor invocation.
2805 SetConstructCallPosition(expr); 2780 SetConstructCallPosition(expr);
2806 2781
2807 // Load new target into rdx. 2782 // Load new target into rdx.
2808 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2783 VisitForAccumulatorValue(super_call_ref->new_target_var());
2809 __ movp(rdx, result_register()); 2784 __ movp(rdx, result_register());
2810 2785
2811 // Load function and argument count into rdi and rax. 2786 // Load function and argument count into rdi and rax.
2812 __ Set(rax, arg_count); 2787 __ Set(rax, arg_count);
2813 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); 2788 __ movp(rdi, Operand(rsp, arg_count * kPointerSize));
2814 2789
2815 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2790 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2791 OperandStackDepthDecrement(arg_count + 1);
2816 2792
2817 RecordJSReturnSite(expr); 2793 RecordJSReturnSite(expr);
2818 2794
2819 // Restore context register. 2795 // Restore context register.
2820 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2796 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2821 2797
2822 context()->Plug(rax); 2798 context()->Plug(rax);
2823 } 2799 }
2824 2800
2825 2801
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
3027 ZoneList<Expression*>* args = expr->arguments(); 3003 ZoneList<Expression*>* args = expr->arguments();
3028 DCHECK_EQ(3, args->length()); 3004 DCHECK_EQ(3, args->length());
3029 3005
3030 Register string = rax; 3006 Register string = rax;
3031 Register index = rbx; 3007 Register index = rbx;
3032 Register value = rcx; 3008 Register value = rcx;
3033 3009
3034 VisitForStackValue(args->at(0)); // index 3010 VisitForStackValue(args->at(0)); // index
3035 VisitForStackValue(args->at(1)); // value 3011 VisitForStackValue(args->at(1)); // value
3036 VisitForAccumulatorValue(args->at(2)); // string 3012 VisitForAccumulatorValue(args->at(2)); // string
3037 __ Pop(value); 3013 PopOperand(value);
3038 __ Pop(index); 3014 PopOperand(index);
3039 3015
3040 if (FLAG_debug_code) { 3016 if (FLAG_debug_code) {
3041 __ Check(__ CheckSmi(value), kNonSmiValue); 3017 __ Check(__ CheckSmi(value), kNonSmiValue);
3042 __ Check(__ CheckSmi(index), kNonSmiValue); 3018 __ Check(__ CheckSmi(index), kNonSmiValue);
3043 } 3019 }
3044 3020
3045 __ SmiToInteger32(value, value); 3021 __ SmiToInteger32(value, value);
3046 __ SmiToInteger32(index, index); 3022 __ SmiToInteger32(index, index);
3047 3023
3048 if (FLAG_debug_code) { 3024 if (FLAG_debug_code) {
(...skipping 11 matching lines...) Expand all
3060 ZoneList<Expression*>* args = expr->arguments(); 3036 ZoneList<Expression*>* args = expr->arguments();
3061 DCHECK_EQ(3, args->length()); 3037 DCHECK_EQ(3, args->length());
3062 3038
3063 Register string = rax; 3039 Register string = rax;
3064 Register index = rbx; 3040 Register index = rbx;
3065 Register value = rcx; 3041 Register value = rcx;
3066 3042
3067 VisitForStackValue(args->at(0)); // index 3043 VisitForStackValue(args->at(0)); // index
3068 VisitForStackValue(args->at(1)); // value 3044 VisitForStackValue(args->at(1)); // value
3069 VisitForAccumulatorValue(args->at(2)); // string 3045 VisitForAccumulatorValue(args->at(2)); // string
3070 __ Pop(value); 3046 PopOperand(value);
3071 __ Pop(index); 3047 PopOperand(index);
3072 3048
3073 if (FLAG_debug_code) { 3049 if (FLAG_debug_code) {
3074 __ Check(__ CheckSmi(value), kNonSmiValue); 3050 __ Check(__ CheckSmi(value), kNonSmiValue);
3075 __ Check(__ CheckSmi(index), kNonSmiValue); 3051 __ Check(__ CheckSmi(index), kNonSmiValue);
3076 } 3052 }
3077 3053
3078 __ SmiToInteger32(value, value); 3054 __ SmiToInteger32(value, value);
3079 __ SmiToInteger32(index, index); 3055 __ SmiToInteger32(index, index);
3080 3056
3081 if (FLAG_debug_code) { 3057 if (FLAG_debug_code) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3129 ZoneList<Expression*>* args = expr->arguments(); 3105 ZoneList<Expression*>* args = expr->arguments();
3130 DCHECK(args->length() == 2); 3106 DCHECK(args->length() == 2);
3131 3107
3132 VisitForStackValue(args->at(0)); 3108 VisitForStackValue(args->at(0));
3133 VisitForAccumulatorValue(args->at(1)); 3109 VisitForAccumulatorValue(args->at(1));
3134 3110
3135 Register object = rbx; 3111 Register object = rbx;
3136 Register index = rax; 3112 Register index = rax;
3137 Register result = rdx; 3113 Register result = rdx;
3138 3114
3139 __ Pop(object); 3115 PopOperand(object);
3140 3116
3141 Label need_conversion; 3117 Label need_conversion;
3142 Label index_out_of_range; 3118 Label index_out_of_range;
3143 Label done; 3119 Label done;
3144 StringCharCodeAtGenerator generator(object, 3120 StringCharCodeAtGenerator generator(object,
3145 index, 3121 index,
3146 result, 3122 result,
3147 &need_conversion, 3123 &need_conversion,
3148 &need_conversion, 3124 &need_conversion,
3149 &index_out_of_range, 3125 &index_out_of_range,
(...skipping 26 matching lines...) Expand all
3176 DCHECK(args->length() == 2); 3152 DCHECK(args->length() == 2);
3177 3153
3178 VisitForStackValue(args->at(0)); 3154 VisitForStackValue(args->at(0));
3179 VisitForAccumulatorValue(args->at(1)); 3155 VisitForAccumulatorValue(args->at(1));
3180 3156
3181 Register object = rbx; 3157 Register object = rbx;
3182 Register index = rax; 3158 Register index = rax;
3183 Register scratch = rdx; 3159 Register scratch = rdx;
3184 Register result = rax; 3160 Register result = rax;
3185 3161
3186 __ Pop(object); 3162 PopOperand(object);
3187 3163
3188 Label need_conversion; 3164 Label need_conversion;
3189 Label index_out_of_range; 3165 Label index_out_of_range;
3190 Label done; 3166 Label done;
3191 StringCharAtGenerator generator(object, 3167 StringCharAtGenerator generator(object,
3192 index, 3168 index,
3193 scratch, 3169 scratch,
3194 result, 3170 result,
3195 &need_conversion, 3171 &need_conversion,
3196 &need_conversion, 3172 &need_conversion,
(...skipping 29 matching lines...) Expand all
3226 for (Expression* const arg : *args) { 3202 for (Expression* const arg : *args) {
3227 VisitForStackValue(arg); 3203 VisitForStackValue(arg);
3228 } 3204 }
3229 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3205 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3230 // Move target to rdi. 3206 // Move target to rdi.
3231 int const argc = args->length() - 2; 3207 int const argc = args->length() - 2;
3232 __ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize)); 3208 __ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize));
3233 // Call the target. 3209 // Call the target.
3234 __ Set(rax, argc); 3210 __ Set(rax, argc);
3235 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3211 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3212 OperandStackDepthDecrement(argc + 1);
3236 // Restore context register. 3213 // Restore context register.
3237 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3214 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3238 // Discard the function left on TOS. 3215 // Discard the function left on TOS.
3239 context()->DropAndPlug(1, rax); 3216 context()->DropAndPlug(1, rax);
3240 } 3217 }
3241 3218
3242 3219
3243 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3220 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3244 ZoneList<Expression*>* args = expr->arguments(); 3221 ZoneList<Expression*>* args = expr->arguments();
3245 DCHECK(args->length() == 1); 3222 DCHECK(args->length() == 1);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3313 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); 3290 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx);
3314 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); 3291 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
3315 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); 3292 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
3316 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); 3293 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx);
3317 __ Pop(FieldOperand(rax, JSIteratorResult::kDoneOffset)); 3294 __ Pop(FieldOperand(rax, JSIteratorResult::kDoneOffset));
3318 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); 3295 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset));
3319 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3296 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3320 __ jmp(&done, Label::kNear); 3297 __ jmp(&done, Label::kNear);
3321 3298
3322 __ bind(&runtime); 3299 __ bind(&runtime);
3323 __ CallRuntime(Runtime::kCreateIterResultObject); 3300 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3324 3301
3325 __ bind(&done); 3302 __ bind(&done);
3326 context()->Plug(rax); 3303 context()->Plug(rax);
3327 } 3304 }
3328 3305
3329 3306
3330 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3307 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3331 // Push the builtins object as receiver. 3308 // Push the builtins object as receiver.
3309 OperandStackDepthIncrement(1);
3332 __ PushRoot(Heap::kUndefinedValueRootIndex); 3310 __ PushRoot(Heap::kUndefinedValueRootIndex);
3333 3311
3334 __ LoadNativeContextSlot(expr->context_index(), rax); 3312 __ LoadNativeContextSlot(expr->context_index(), rax);
3335 } 3313 }
3336 3314
3337 3315
3338 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3316 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3339 ZoneList<Expression*>* args = expr->arguments(); 3317 ZoneList<Expression*>* args = expr->arguments();
3340 int arg_count = args->length(); 3318 int arg_count = args->length();
3341 3319
3342 SetCallPosition(expr); 3320 SetCallPosition(expr);
3343 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 3321 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
3344 __ Set(rax, arg_count); 3322 __ Set(rax, arg_count);
3345 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3323 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3346 RelocInfo::CODE_TARGET); 3324 RelocInfo::CODE_TARGET);
3325 OperandStackDepthDecrement(arg_count + 1);
3347 } 3326 }
3348 3327
3349 3328
3350 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3329 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3351 ZoneList<Expression*>* args = expr->arguments(); 3330 ZoneList<Expression*>* args = expr->arguments();
3352 int arg_count = args->length(); 3331 int arg_count = args->length();
3353 3332
3354 if (expr->is_jsruntime()) { 3333 if (expr->is_jsruntime()) {
3355 Comment cmnt(masm_, "[ CallRuntime"); 3334 Comment cmnt(masm_, "[ CallRuntime");
3356 3335
3357 EmitLoadJSRuntimeFunction(expr); 3336 EmitLoadJSRuntimeFunction(expr);
3358 3337
3359 // Push the target function under the receiver. 3338 // Push the target function under the receiver.
3360 __ Push(Operand(rsp, 0)); 3339 PushOperand(Operand(rsp, 0));
3361 __ movp(Operand(rsp, kPointerSize), rax); 3340 __ movp(Operand(rsp, kPointerSize), rax);
3362 3341
3363 // Push the arguments ("left-to-right"). 3342 // Push the arguments ("left-to-right").
3364 for (int i = 0; i < arg_count; i++) { 3343 for (int i = 0; i < arg_count; i++) {
3365 VisitForStackValue(args->at(i)); 3344 VisitForStackValue(args->at(i));
3366 } 3345 }
3367 3346
3368 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3347 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3369 EmitCallJSRuntimeFunction(expr); 3348 EmitCallJSRuntimeFunction(expr);
3370 3349
(...skipping 14 matching lines...) Expand all
3385 default: { 3364 default: {
3386 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3365 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3387 // Push the arguments ("left-to-right"). 3366 // Push the arguments ("left-to-right").
3388 for (int i = 0; i < arg_count; i++) { 3367 for (int i = 0; i < arg_count; i++) {
3389 VisitForStackValue(args->at(i)); 3368 VisitForStackValue(args->at(i));
3390 } 3369 }
3391 3370
3392 // Call the C runtime. 3371 // Call the C runtime.
3393 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3372 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3394 __ CallRuntime(function, arg_count); 3373 __ CallRuntime(function, arg_count);
3374 OperandStackDepthDecrement(arg_count);
3395 context()->Plug(rax); 3375 context()->Plug(rax);
3396 } 3376 }
3397 } 3377 }
3398 } 3378 }
3399 } 3379 }
3400 3380
3401 3381
3402 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3382 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3403 switch (expr->op()) { 3383 switch (expr->op()) {
3404 case Token::DELETE: { 3384 case Token::DELETE: {
3405 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3385 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3406 Property* property = expr->expression()->AsProperty(); 3386 Property* property = expr->expression()->AsProperty();
3407 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3387 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3408 3388
3409 if (property != NULL) { 3389 if (property != NULL) {
3410 VisitForStackValue(property->obj()); 3390 VisitForStackValue(property->obj());
3411 VisitForStackValue(property->key()); 3391 VisitForStackValue(property->key());
3412 __ CallRuntime(is_strict(language_mode()) 3392 CallRuntimeWithOperands(is_strict(language_mode())
3413 ? Runtime::kDeleteProperty_Strict 3393 ? Runtime::kDeleteProperty_Strict
3414 : Runtime::kDeleteProperty_Sloppy); 3394 : Runtime::kDeleteProperty_Sloppy);
3415 context()->Plug(rax); 3395 context()->Plug(rax);
3416 } else if (proxy != NULL) { 3396 } else if (proxy != NULL) {
3417 Variable* var = proxy->var(); 3397 Variable* var = proxy->var();
3418 // Delete of an unqualified identifier is disallowed in strict mode but 3398 // Delete of an unqualified identifier is disallowed in strict mode but
3419 // "delete this" is allowed. 3399 // "delete this" is allowed.
3420 bool is_this = var->HasThisName(isolate()); 3400 bool is_this = var->HasThisName(isolate());
3421 DCHECK(is_sloppy(language_mode()) || is_this); 3401 DCHECK(is_sloppy(language_mode()) || is_this);
3422 if (var->IsUnallocatedOrGlobalSlot()) { 3402 if (var->IsUnallocatedOrGlobalSlot()) {
3423 __ movp(rax, NativeContextOperand()); 3403 __ movp(rax, NativeContextOperand());
3424 __ Push(ContextOperand(rax, Context::EXTENSION_INDEX)); 3404 __ Push(ContextOperand(rax, Context::EXTENSION_INDEX));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3471 // We handle value contexts explicitly rather than simply visiting 3451 // We handle value contexts explicitly rather than simply visiting
3472 // for control and plugging the control flow into the context, 3452 // for control and plugging the control flow into the context,
3473 // because we need to prepare a pair of extra administrative AST ids 3453 // because we need to prepare a pair of extra administrative AST ids
3474 // for the optimizing compiler. 3454 // for the optimizing compiler.
3475 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3455 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3476 Label materialize_true, materialize_false, done; 3456 Label materialize_true, materialize_false, done;
3477 VisitForControl(expr->expression(), 3457 VisitForControl(expr->expression(),
3478 &materialize_false, 3458 &materialize_false,
3479 &materialize_true, 3459 &materialize_true,
3480 &materialize_true); 3460 &materialize_true);
3461 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3481 __ bind(&materialize_true); 3462 __ bind(&materialize_true);
3482 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3463 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3483 if (context()->IsAccumulatorValue()) { 3464 if (context()->IsAccumulatorValue()) {
3484 __ LoadRoot(rax, Heap::kTrueValueRootIndex); 3465 __ LoadRoot(rax, Heap::kTrueValueRootIndex);
3485 } else { 3466 } else {
3486 __ PushRoot(Heap::kTrueValueRootIndex); 3467 __ PushRoot(Heap::kTrueValueRootIndex);
3487 } 3468 }
3488 __ jmp(&done, Label::kNear); 3469 __ jmp(&done, Label::kNear);
3489 __ bind(&materialize_false); 3470 __ bind(&materialize_false);
3490 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3471 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3526 LhsKind assign_type = Property::GetAssignType(prop); 3507 LhsKind assign_type = Property::GetAssignType(prop);
3527 3508
3528 // Evaluate expression and get value. 3509 // Evaluate expression and get value.
3529 if (assign_type == VARIABLE) { 3510 if (assign_type == VARIABLE) {
3530 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3511 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3531 AccumulatorValueContext context(this); 3512 AccumulatorValueContext context(this);
3532 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3513 EmitVariableLoad(expr->expression()->AsVariableProxy());
3533 } else { 3514 } else {
3534 // Reserve space for result of postfix operation. 3515 // Reserve space for result of postfix operation.
3535 if (expr->is_postfix() && !context()->IsEffect()) { 3516 if (expr->is_postfix() && !context()->IsEffect()) {
3536 __ Push(Smi::FromInt(0)); 3517 PushOperand(Smi::FromInt(0));
3537 } 3518 }
3538 switch (assign_type) { 3519 switch (assign_type) {
3539 case NAMED_PROPERTY: { 3520 case NAMED_PROPERTY: {
3540 VisitForStackValue(prop->obj()); 3521 VisitForStackValue(prop->obj());
3541 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 3522 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
3542 EmitNamedPropertyLoad(prop); 3523 EmitNamedPropertyLoad(prop);
3543 break; 3524 break;
3544 } 3525 }
3545 3526
3546 case NAMED_SUPER_PROPERTY: { 3527 case NAMED_SUPER_PROPERTY: {
3547 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3528 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3548 VisitForAccumulatorValue( 3529 VisitForAccumulatorValue(
3549 prop->obj()->AsSuperPropertyReference()->home_object()); 3530 prop->obj()->AsSuperPropertyReference()->home_object());
3550 __ Push(result_register()); 3531 PushOperand(result_register());
3551 __ Push(MemOperand(rsp, kPointerSize)); 3532 PushOperand(MemOperand(rsp, kPointerSize));
3552 __ Push(result_register()); 3533 PushOperand(result_register());
3553 EmitNamedSuperPropertyLoad(prop); 3534 EmitNamedSuperPropertyLoad(prop);
3554 break; 3535 break;
3555 } 3536 }
3556 3537
3557 case KEYED_SUPER_PROPERTY: { 3538 case KEYED_SUPER_PROPERTY: {
3558 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3539 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3559 VisitForStackValue( 3540 VisitForStackValue(
3560 prop->obj()->AsSuperPropertyReference()->home_object()); 3541 prop->obj()->AsSuperPropertyReference()->home_object());
3561 VisitForAccumulatorValue(prop->key()); 3542 VisitForAccumulatorValue(prop->key());
3562 __ Push(result_register()); 3543 PushOperand(result_register());
3563 __ Push(MemOperand(rsp, 2 * kPointerSize)); 3544 PushOperand(MemOperand(rsp, 2 * kPointerSize));
3564 __ Push(MemOperand(rsp, 2 * kPointerSize)); 3545 PushOperand(MemOperand(rsp, 2 * kPointerSize));
3565 __ Push(result_register()); 3546 PushOperand(result_register());
3566 EmitKeyedSuperPropertyLoad(prop); 3547 EmitKeyedSuperPropertyLoad(prop);
3567 break; 3548 break;
3568 } 3549 }
3569 3550
3570 case KEYED_PROPERTY: { 3551 case KEYED_PROPERTY: {
3571 VisitForStackValue(prop->obj()); 3552 VisitForStackValue(prop->obj());
3572 VisitForStackValue(prop->key()); 3553 VisitForStackValue(prop->key());
3573 // Leave receiver on stack 3554 // Leave receiver on stack
3574 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); 3555 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize));
3575 // Copy of key, needed for later store. 3556 // Copy of key, needed for later store.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3644 } 3625 }
3645 3626
3646 // Save result for postfix expressions. 3627 // Save result for postfix expressions.
3647 if (expr->is_postfix()) { 3628 if (expr->is_postfix()) {
3648 if (!context()->IsEffect()) { 3629 if (!context()->IsEffect()) {
3649 // Save the result on the stack. If we have a named or keyed property 3630 // Save the result on the stack. If we have a named or keyed property
3650 // we store the result under the receiver that is currently on top 3631 // we store the result under the receiver that is currently on top
3651 // of the stack. 3632 // of the stack.
3652 switch (assign_type) { 3633 switch (assign_type) {
3653 case VARIABLE: 3634 case VARIABLE:
3654 __ Push(rax); 3635 PushOperand(rax);
3655 break; 3636 break;
3656 case NAMED_PROPERTY: 3637 case NAMED_PROPERTY:
3657 __ movp(Operand(rsp, kPointerSize), rax); 3638 __ movp(Operand(rsp, kPointerSize), rax);
3658 break; 3639 break;
3659 case NAMED_SUPER_PROPERTY: 3640 case NAMED_SUPER_PROPERTY:
3660 __ movp(Operand(rsp, 2 * kPointerSize), rax); 3641 __ movp(Operand(rsp, 2 * kPointerSize), rax);
3661 break; 3642 break;
3662 case KEYED_PROPERTY: 3643 case KEYED_PROPERTY:
3663 __ movp(Operand(rsp, 2 * kPointerSize), rax); 3644 __ movp(Operand(rsp, 2 * kPointerSize), rax);
3664 break; 3645 break;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3704 // Perform the assignment as if via '='. 3685 // Perform the assignment as if via '='.
3705 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3686 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3706 Token::ASSIGN, expr->CountSlot()); 3687 Token::ASSIGN, expr->CountSlot());
3707 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3688 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3708 context()->Plug(rax); 3689 context()->Plug(rax);
3709 } 3690 }
3710 break; 3691 break;
3711 case NAMED_PROPERTY: { 3692 case NAMED_PROPERTY: {
3712 __ Move(StoreDescriptor::NameRegister(), 3693 __ Move(StoreDescriptor::NameRegister(),
3713 prop->key()->AsLiteral()->value()); 3694 prop->key()->AsLiteral()->value());
3714 __ Pop(StoreDescriptor::ReceiverRegister()); 3695 PopOperand(StoreDescriptor::ReceiverRegister());
3715 EmitLoadStoreICSlot(expr->CountSlot()); 3696 EmitLoadStoreICSlot(expr->CountSlot());
3716 CallStoreIC(); 3697 CallStoreIC();
3717 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3698 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3718 if (expr->is_postfix()) { 3699 if (expr->is_postfix()) {
3719 if (!context()->IsEffect()) { 3700 if (!context()->IsEffect()) {
3720 context()->PlugTOS(); 3701 context()->PlugTOS();
3721 } 3702 }
3722 } else { 3703 } else {
3723 context()->Plug(rax); 3704 context()->Plug(rax);
3724 } 3705 }
(...skipping 15 matching lines...) Expand all
3740 if (expr->is_postfix()) { 3721 if (expr->is_postfix()) {
3741 if (!context()->IsEffect()) { 3722 if (!context()->IsEffect()) {
3742 context()->PlugTOS(); 3723 context()->PlugTOS();
3743 } 3724 }
3744 } else { 3725 } else {
3745 context()->Plug(rax); 3726 context()->Plug(rax);
3746 } 3727 }
3747 break; 3728 break;
3748 } 3729 }
3749 case KEYED_PROPERTY: { 3730 case KEYED_PROPERTY: {
3750 __ Pop(StoreDescriptor::NameRegister()); 3731 PopOperand(StoreDescriptor::NameRegister());
3751 __ Pop(StoreDescriptor::ReceiverRegister()); 3732 PopOperand(StoreDescriptor::ReceiverRegister());
3752 Handle<Code> ic = 3733 Handle<Code> ic =
3753 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3734 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3754 EmitLoadStoreICSlot(expr->CountSlot()); 3735 EmitLoadStoreICSlot(expr->CountSlot());
3755 CallIC(ic); 3736 CallIC(ic);
3756 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3737 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3757 if (expr->is_postfix()) { 3738 if (expr->is_postfix()) {
3758 if (!context()->IsEffect()) { 3739 if (!context()->IsEffect()) {
3759 context()->PlugTOS(); 3740 context()->PlugTOS();
3760 } 3741 }
3761 } else { 3742 } else {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3862 Label* if_false = NULL; 3843 Label* if_false = NULL;
3863 Label* fall_through = NULL; 3844 Label* fall_through = NULL;
3864 context()->PrepareTest(&materialize_true, &materialize_false, 3845 context()->PrepareTest(&materialize_true, &materialize_false,
3865 &if_true, &if_false, &fall_through); 3846 &if_true, &if_false, &fall_through);
3866 3847
3867 Token::Value op = expr->op(); 3848 Token::Value op = expr->op();
3868 VisitForStackValue(expr->left()); 3849 VisitForStackValue(expr->left());
3869 switch (op) { 3850 switch (op) {
3870 case Token::IN: 3851 case Token::IN:
3871 VisitForStackValue(expr->right()); 3852 VisitForStackValue(expr->right());
3872 __ CallRuntime(Runtime::kHasProperty); 3853 CallRuntimeWithOperands(Runtime::kHasProperty);
3873 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3854 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3874 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 3855 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
3875 Split(equal, if_true, if_false, fall_through); 3856 Split(equal, if_true, if_false, fall_through);
3876 break; 3857 break;
3877 3858
3878 case Token::INSTANCEOF: { 3859 case Token::INSTANCEOF: {
3879 VisitForAccumulatorValue(expr->right()); 3860 VisitForAccumulatorValue(expr->right());
3880 __ Pop(rdx); 3861 PopOperand(rdx);
3881 InstanceOfStub stub(isolate()); 3862 InstanceOfStub stub(isolate());
3882 __ CallStub(&stub); 3863 __ CallStub(&stub);
3883 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3864 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3884 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 3865 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
3885 Split(equal, if_true, if_false, fall_through); 3866 Split(equal, if_true, if_false, fall_through);
3886 break; 3867 break;
3887 } 3868 }
3888 3869
3889 default: { 3870 default: {
3890 VisitForAccumulatorValue(expr->right()); 3871 VisitForAccumulatorValue(expr->right());
3891 Condition cc = CompareIC::ComputeCondition(op); 3872 Condition cc = CompareIC::ComputeCondition(op);
3892 __ Pop(rdx); 3873 PopOperand(rdx);
3893 3874
3894 bool inline_smi_code = ShouldInlineSmiCase(op); 3875 bool inline_smi_code = ShouldInlineSmiCase(op);
3895 JumpPatchSite patch_site(masm_); 3876 JumpPatchSite patch_site(masm_);
3896 if (inline_smi_code) { 3877 if (inline_smi_code) {
3897 Label slow_case; 3878 Label slow_case;
3898 __ movp(rcx, rdx); 3879 __ movp(rcx, rdx);
3899 __ orp(rcx, rax); 3880 __ orp(rcx, rax);
3900 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); 3881 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear);
3901 __ cmpp(rdx, rax); 3882 __ cmpp(rdx, rax);
3902 Split(cc, if_true, if_false, NULL); 3883 Split(cc, if_true, if_false, NULL);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3975 3956
3976 3957
3977 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { 3958 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
3978 Scope* closure_scope = scope()->ClosureScope(); 3959 Scope* closure_scope = scope()->ClosureScope();
3979 if (closure_scope->is_script_scope() || 3960 if (closure_scope->is_script_scope() ||
3980 closure_scope->is_module_scope()) { 3961 closure_scope->is_module_scope()) {
3981 // Contexts nested in the native context have a canonical empty function 3962 // Contexts nested in the native context have a canonical empty function
3982 // as their closure, not the anonymous closure containing the global 3963 // as their closure, not the anonymous closure containing the global
3983 // code. 3964 // code.
3984 __ movp(rax, NativeContextOperand()); 3965 __ movp(rax, NativeContextOperand());
3985 __ Push(ContextOperand(rax, Context::CLOSURE_INDEX)); 3966 PushOperand(ContextOperand(rax, Context::CLOSURE_INDEX));
3986 } else if (closure_scope->is_eval_scope()) { 3967 } else if (closure_scope->is_eval_scope()) {
3987 // Contexts created by a call to eval have the same closure as the 3968 // Contexts created by a call to eval have the same closure as the
3988 // context calling eval, not the anonymous closure containing the eval 3969 // context calling eval, not the anonymous closure containing the eval
3989 // code. Fetch it from the context. 3970 // code. Fetch it from the context.
3990 __ Push(ContextOperand(rsi, Context::CLOSURE_INDEX)); 3971 PushOperand(ContextOperand(rsi, Context::CLOSURE_INDEX));
3991 } else { 3972 } else {
3992 DCHECK(closure_scope->is_function_scope()); 3973 DCHECK(closure_scope->is_function_scope());
3993 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 3974 PushOperand(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
3994 } 3975 }
3995 } 3976 }
3996 3977
3997 3978
3998 // ---------------------------------------------------------------------------- 3979 // ----------------------------------------------------------------------------
3999 // Non-local control flow support. 3980 // Non-local control flow support.
4000 3981
4001 3982
4002 void FullCodeGenerator::EnterFinallyBlock() { 3983 void FullCodeGenerator::EnterFinallyBlock() {
4003 DCHECK(!result_register().is(rdx)); 3984 DCHECK(!result_register().is(rdx));
4004 3985
4005 // Store pending message while executing finally block. 3986 // Store pending message while executing finally block.
4006 ExternalReference pending_message_obj = 3987 ExternalReference pending_message_obj =
4007 ExternalReference::address_of_pending_message_obj(isolate()); 3988 ExternalReference::address_of_pending_message_obj(isolate());
4008 __ Load(rdx, pending_message_obj); 3989 __ Load(rdx, pending_message_obj);
4009 __ Push(rdx); 3990 PushOperand(rdx);
4010 3991
4011 ClearPendingMessage(); 3992 ClearPendingMessage();
4012 } 3993 }
4013 3994
4014 3995
4015 void FullCodeGenerator::ExitFinallyBlock() { 3996 void FullCodeGenerator::ExitFinallyBlock() {
4016 DCHECK(!result_register().is(rdx)); 3997 DCHECK(!result_register().is(rdx));
4017 // Restore pending message from stack. 3998 // Restore pending message from stack.
4018 __ Pop(rdx); 3999 PopOperand(rdx);
4019 ExternalReference pending_message_obj = 4000 ExternalReference pending_message_obj =
4020 ExternalReference::address_of_pending_message_obj(isolate()); 4001 ExternalReference::address_of_pending_message_obj(isolate());
4021 __ Store(pending_message_obj, rdx); 4002 __ Store(pending_message_obj, rdx);
4022 } 4003 }
4023 4004
4024 4005
4025 void FullCodeGenerator::ClearPendingMessage() { 4006 void FullCodeGenerator::ClearPendingMessage() {
4026 DCHECK(!result_register().is(rdx)); 4007 DCHECK(!result_register().is(rdx));
4027 ExternalReference pending_message_obj = 4008 ExternalReference pending_message_obj =
4028 ExternalReference::address_of_pending_message_obj(isolate()); 4009 ExternalReference::address_of_pending_message_obj(isolate());
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
4138 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4119 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4139 Assembler::target_address_at(call_target_address, 4120 Assembler::target_address_at(call_target_address,
4140 unoptimized_code)); 4121 unoptimized_code));
4141 return OSR_AFTER_STACK_CHECK; 4122 return OSR_AFTER_STACK_CHECK;
4142 } 4123 }
4143 4124
4144 } // namespace internal 4125 } // namespace internal
4145 } // namespace v8 4126 } // namespace v8
4146 4127
4147 #endif // V8_TARGET_ARCH_X64 4128 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/full-codegen/ppc/full-codegen-ppc.cc ('k') | src/full-codegen/x87/full-codegen-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698