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 (FLAG_debug_code) { |
| 1988 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp + |
| 1989 operand_stack_depth_ * kPointerSize; |
| 1990 __ movp(rax, rbp); |
| 1991 __ subp(rax, rsp); |
| 1992 __ cmpp(rax, Immediate(expected_diff)); |
| 1993 __ Assert(equal, kUnexpectedStackDepth); |
| 1994 } |
| 1995 } |
1999 | 1996 |
2000 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 1997 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
2001 Label allocate, done_allocate; | 1998 Label allocate, done_allocate; |
2002 | 1999 |
2003 __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &allocate, TAG_OBJECT); | 2000 __ Allocate(JSIteratorResult::kSize, rax, rcx, rdx, &allocate, TAG_OBJECT); |
2004 __ jmp(&done_allocate, Label::kNear); | 2001 __ jmp(&done_allocate, Label::kNear); |
2005 | 2002 |
2006 __ bind(&allocate); | 2003 __ bind(&allocate); |
2007 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 2004 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
2008 __ CallRuntime(Runtime::kAllocateInNewSpace); | 2005 __ CallRuntime(Runtime::kAllocateInNewSpace); |
2009 | 2006 |
2010 __ bind(&done_allocate); | 2007 __ bind(&done_allocate); |
2011 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, rbx); | 2008 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, rbx); |
2012 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); | 2009 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); |
2013 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); | 2010 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); |
2014 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); | 2011 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); |
2015 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); | 2012 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); |
2016 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); | 2013 __ Pop(FieldOperand(rax, JSIteratorResult::kValueOffset)); |
2017 __ LoadRoot(FieldOperand(rax, JSIteratorResult::kDoneOffset), | 2014 __ LoadRoot(FieldOperand(rax, JSIteratorResult::kDoneOffset), |
2018 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 2015 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); |
2019 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 2016 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
2020 } | 2017 } |
2021 | 2018 |
2022 | 2019 |
2023 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2020 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2024 SetExpressionPosition(prop); | 2021 SetExpressionPosition(prop); |
2025 Literal* key = prop->key()->AsLiteral(); | 2022 Literal* key = prop->key()->AsLiteral(); |
| 2023 DCHECK(!key->value()->IsSmi()); |
2026 DCHECK(!prop->IsSuperAccess()); | 2024 DCHECK(!prop->IsSuperAccess()); |
2027 | 2025 |
2028 __ Move(LoadDescriptor::NameRegister(), key->value()); | 2026 __ Move(LoadDescriptor::NameRegister(), key->value()); |
2029 __ Move(LoadDescriptor::SlotRegister(), | 2027 __ Move(LoadDescriptor::SlotRegister(), |
2030 SmiFromSlot(prop->PropertyFeedbackSlot())); | 2028 SmiFromSlot(prop->PropertyFeedbackSlot())); |
2031 CallLoadIC(NOT_INSIDE_TYPEOF); | 2029 CallLoadIC(NOT_INSIDE_TYPEOF); |
2032 } | 2030 } |
2033 | 2031 |
2034 | 2032 |
2035 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | |
2036 // Stack: receiver, home_object | |
2037 SetExpressionPosition(prop); | |
2038 Literal* key = prop->key()->AsLiteral(); | |
2039 DCHECK(!key->value()->IsSmi()); | |
2040 DCHECK(prop->IsSuperAccess()); | |
2041 | |
2042 __ Push(key->value()); | |
2043 __ CallRuntime(Runtime::kLoadFromSuper); | |
2044 } | |
2045 | |
2046 | |
2047 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | |
2048 SetExpressionPosition(prop); | |
2049 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | |
2050 __ Move(LoadDescriptor::SlotRegister(), | |
2051 SmiFromSlot(prop->PropertyFeedbackSlot())); | |
2052 CallIC(ic); | |
2053 } | |
2054 | |
2055 | |
2056 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | |
2057 // Stack: receiver, home_object, key. | |
2058 SetExpressionPosition(prop); | |
2059 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | |
2060 } | |
2061 | |
2062 | |
2063 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2033 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2064 Token::Value op, | 2034 Token::Value op, |
2065 Expression* left, | 2035 Expression* left, |
2066 Expression* right) { | 2036 Expression* right) { |
2067 // Do combined smi check of the operands. Left operand is on the | 2037 // Do combined smi check of the operands. Left operand is on the |
2068 // stack (popped into rdx). Right operand is in rax but moved into | 2038 // stack (popped into rdx). Right operand is in rax but moved into |
2069 // rcx to make the shifts easier. | 2039 // rcx to make the shifts easier. |
2070 Label done, stub_call, smi_case; | 2040 Label done, stub_call, smi_case; |
2071 __ Pop(rdx); | 2041 PopOperand(rdx); |
2072 __ movp(rcx, rax); | 2042 __ movp(rcx, rax); |
2073 __ orp(rax, rdx); | 2043 __ orp(rax, rdx); |
2074 JumpPatchSite patch_site(masm_); | 2044 JumpPatchSite patch_site(masm_); |
2075 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); | 2045 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); |
2076 | 2046 |
2077 __ bind(&stub_call); | 2047 __ bind(&stub_call); |
2078 __ movp(rax, rcx); | 2048 __ movp(rax, rcx); |
2079 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 2049 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
2080 CallIC(code, expr->BinaryOperationFeedbackId()); | 2050 CallIC(code, expr->BinaryOperationFeedbackId()); |
2081 patch_site.EmitPatchInfo(); | 2051 patch_site.EmitPatchInfo(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 |