| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 (generate_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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |