OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 // Push(lr, fp, cp, x1); | 128 // Push(lr, fp, cp, x1); |
129 // Add(fp, jssp, 2 * kPointerSize); | 129 // Add(fp, jssp, 2 * kPointerSize); |
130 info->set_prologue_offset(masm_->pc_offset()); | 130 info->set_prologue_offset(masm_->pc_offset()); |
131 __ Prologue(info->GeneratePreagedPrologue()); | 131 __ Prologue(info->GeneratePreagedPrologue()); |
132 | 132 |
133 // Reserve space on the stack for locals. | 133 // Reserve space on the stack for locals. |
134 { Comment cmnt(masm_, "[ Allocate locals"); | 134 { Comment cmnt(masm_, "[ Allocate locals"); |
135 int locals_count = info->scope()->num_stack_slots(); | 135 int locals_count = info->scope()->num_stack_slots(); |
136 // Generators allocate locals, if any, in context slots. | 136 // Generators allocate locals, if any, in context slots. |
137 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); | 137 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); |
138 | 138 OperandStackDepthIncrement(locals_count); |
139 if (locals_count > 0) { | 139 if (locals_count > 0) { |
140 if (locals_count >= 128) { | 140 if (locals_count >= 128) { |
141 Label ok; | 141 Label ok; |
142 DCHECK(jssp.Is(__ StackPointer())); | 142 DCHECK(jssp.Is(__ StackPointer())); |
143 __ Sub(x10, jssp, locals_count * kPointerSize); | 143 __ Sub(x10, jssp, locals_count * kPointerSize); |
144 __ CompareRoot(x10, Heap::kRealStackLimitRootIndex); | 144 __ CompareRoot(x10, Heap::kRealStackLimitRootIndex); |
145 __ B(hs, &ok); | 145 __ B(hs, &ok); |
146 __ CallRuntime(Runtime::kThrowStackOverflow); | 146 __ CallRuntime(Runtime::kThrowStackOverflow); |
147 __ Bind(&ok); | 147 __ Bind(&ok); |
148 } | 148 } |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 __ Ret(); | 463 __ Ret(); |
464 int32_t arg_count = info_->scope()->num_parameters() + 1; | 464 int32_t arg_count = info_->scope()->num_parameters() + 1; |
465 __ dc64(kXRegSize * arg_count); | 465 __ dc64(kXRegSize * arg_count); |
466 } | 466 } |
467 } | 467 } |
468 | 468 |
469 | 469 |
470 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 470 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
471 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 471 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
472 codegen()->GetVar(result_register(), var); | 472 codegen()->GetVar(result_register(), var); |
473 __ Push(result_register()); | 473 codegen()->PushOperand(result_register()); |
474 } | 474 } |
475 | 475 |
476 | 476 |
477 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 477 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
478 // Root values have no side effects. | 478 // Root values have no side effects. |
479 } | 479 } |
480 | 480 |
481 | 481 |
482 void FullCodeGenerator::AccumulatorValueContext::Plug( | 482 void FullCodeGenerator::AccumulatorValueContext::Plug( |
483 Heap::RootListIndex index) const { | 483 Heap::RootListIndex index) const { |
484 __ LoadRoot(result_register(), index); | 484 __ LoadRoot(result_register(), index); |
485 } | 485 } |
486 | 486 |
487 | 487 |
488 void FullCodeGenerator::StackValueContext::Plug( | 488 void FullCodeGenerator::StackValueContext::Plug( |
489 Heap::RootListIndex index) const { | 489 Heap::RootListIndex index) const { |
490 __ LoadRoot(result_register(), index); | 490 __ LoadRoot(result_register(), index); |
491 __ Push(result_register()); | 491 codegen()->PushOperand(result_register()); |
492 } | 492 } |
493 | 493 |
494 | 494 |
495 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { | 495 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { |
496 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, | 496 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, |
497 false_label_); | 497 false_label_); |
498 if (index == Heap::kUndefinedValueRootIndex || | 498 if (index == Heap::kUndefinedValueRootIndex || |
499 index == Heap::kNullValueRootIndex || | 499 index == Heap::kNullValueRootIndex || |
500 index == Heap::kFalseValueRootIndex) { | 500 index == Heap::kFalseValueRootIndex) { |
501 if (false_label_ != fall_through_) __ B(false_label_); | 501 if (false_label_ != fall_through_) __ B(false_label_); |
(...skipping 12 matching lines...) Expand all Loading... |
514 | 514 |
515 void FullCodeGenerator::AccumulatorValueContext::Plug( | 515 void FullCodeGenerator::AccumulatorValueContext::Plug( |
516 Handle<Object> lit) const { | 516 Handle<Object> lit) const { |
517 __ Mov(result_register(), Operand(lit)); | 517 __ Mov(result_register(), Operand(lit)); |
518 } | 518 } |
519 | 519 |
520 | 520 |
521 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { | 521 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
522 // Immediates cannot be pushed directly. | 522 // Immediates cannot be pushed directly. |
523 __ Mov(result_register(), Operand(lit)); | 523 __ Mov(result_register(), Operand(lit)); |
524 __ Push(result_register()); | 524 codegen()->PushOperand(result_register()); |
525 } | 525 } |
526 | 526 |
527 | 527 |
528 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { | 528 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
529 codegen()->PrepareForBailoutBeforeSplit(condition(), | 529 codegen()->PrepareForBailoutBeforeSplit(condition(), |
530 true, | 530 true, |
531 true_label_, | 531 true_label_, |
532 false_label_); | 532 false_label_); |
533 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); | 533 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); |
534 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { | 534 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { |
(...skipping 13 matching lines...) Expand all Loading... |
548 if (true_label_ != fall_through_) __ B(true_label_); | 548 if (true_label_ != fall_through_) __ B(true_label_); |
549 } | 549 } |
550 } else { | 550 } else { |
551 // For simplicity we always test the accumulator register. | 551 // For simplicity we always test the accumulator register. |
552 __ Mov(result_register(), Operand(lit)); | 552 __ Mov(result_register(), Operand(lit)); |
553 codegen()->DoTest(this); | 553 codegen()->DoTest(this); |
554 } | 554 } |
555 } | 555 } |
556 | 556 |
557 | 557 |
558 void FullCodeGenerator::EffectContext::DropAndPlug(int count, | |
559 Register reg) const { | |
560 DCHECK(count > 0); | |
561 __ Drop(count); | |
562 } | |
563 | |
564 | |
565 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( | |
566 int count, | |
567 Register reg) const { | |
568 DCHECK(count > 0); | |
569 __ Drop(count); | |
570 __ Move(result_register(), reg); | |
571 } | |
572 | |
573 | |
574 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, | 558 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, |
575 Register reg) const { | 559 Register reg) const { |
576 DCHECK(count > 0); | 560 DCHECK(count > 0); |
577 if (count > 1) __ Drop(count - 1); | 561 if (count > 1) codegen()->DropOperands(count - 1); |
578 __ Poke(reg, 0); | 562 __ Poke(reg, 0); |
579 } | 563 } |
580 | 564 |
581 | 565 |
582 void FullCodeGenerator::TestContext::DropAndPlug(int count, | |
583 Register reg) const { | |
584 DCHECK(count > 0); | |
585 // For simplicity we always test the accumulator register. | |
586 __ Drop(count); | |
587 __ Mov(result_register(), reg); | |
588 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); | |
589 codegen()->DoTest(this); | |
590 } | |
591 | |
592 | |
593 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, | 566 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, |
594 Label* materialize_false) const { | 567 Label* materialize_false) const { |
595 DCHECK(materialize_true == materialize_false); | 568 DCHECK(materialize_true == materialize_false); |
596 __ Bind(materialize_true); | 569 __ Bind(materialize_true); |
597 } | 570 } |
598 | 571 |
599 | 572 |
600 void FullCodeGenerator::AccumulatorValueContext::Plug( | 573 void FullCodeGenerator::AccumulatorValueContext::Plug( |
601 Label* materialize_true, | 574 Label* materialize_true, |
602 Label* materialize_false) const { | 575 Label* materialize_false) const { |
(...skipping 10 matching lines...) Expand all Loading... |
613 void FullCodeGenerator::StackValueContext::Plug( | 586 void FullCodeGenerator::StackValueContext::Plug( |
614 Label* materialize_true, | 587 Label* materialize_true, |
615 Label* materialize_false) const { | 588 Label* materialize_false) const { |
616 Label done; | 589 Label done; |
617 __ Bind(materialize_true); | 590 __ Bind(materialize_true); |
618 __ LoadRoot(x10, Heap::kTrueValueRootIndex); | 591 __ LoadRoot(x10, Heap::kTrueValueRootIndex); |
619 __ B(&done); | 592 __ B(&done); |
620 __ Bind(materialize_false); | 593 __ Bind(materialize_false); |
621 __ LoadRoot(x10, Heap::kFalseValueRootIndex); | 594 __ LoadRoot(x10, Heap::kFalseValueRootIndex); |
622 __ Bind(&done); | 595 __ Bind(&done); |
623 __ Push(x10); | 596 codegen()->PushOperand(x10); |
624 } | 597 } |
625 | 598 |
626 | 599 |
627 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 600 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
628 Label* materialize_false) const { | 601 Label* materialize_false) const { |
629 DCHECK(materialize_true == true_label_); | 602 DCHECK(materialize_true == true_label_); |
630 DCHECK(materialize_false == false_label_); | 603 DCHECK(materialize_false == false_label_); |
631 } | 604 } |
632 | 605 |
633 | 606 |
634 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 607 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
635 Heap::RootListIndex value_root_index = | 608 Heap::RootListIndex value_root_index = |
636 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 609 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
637 __ LoadRoot(result_register(), value_root_index); | 610 __ LoadRoot(result_register(), value_root_index); |
638 } | 611 } |
639 | 612 |
640 | 613 |
641 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 614 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
642 Heap::RootListIndex value_root_index = | 615 Heap::RootListIndex value_root_index = |
643 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 616 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
644 __ LoadRoot(x10, value_root_index); | 617 __ LoadRoot(x10, value_root_index); |
645 __ Push(x10); | 618 codegen()->PushOperand(x10); |
646 } | 619 } |
647 | 620 |
648 | 621 |
649 void FullCodeGenerator::TestContext::Plug(bool flag) const { | 622 void FullCodeGenerator::TestContext::Plug(bool flag) const { |
650 codegen()->PrepareForBailoutBeforeSplit(condition(), | 623 codegen()->PrepareForBailoutBeforeSplit(condition(), |
651 true, | 624 true, |
652 true_label_, | 625 true_label_, |
653 false_label_); | 626 false_label_); |
654 if (flag) { | 627 if (flag) { |
655 if (true_label_ != fall_through_) { | 628 if (true_label_ != fall_through_) { |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 kDontSaveFPRegs, | 858 kDontSaveFPRegs, |
886 EMIT_REMEMBERED_SET, | 859 EMIT_REMEMBERED_SET, |
887 OMIT_SMI_CHECK); | 860 OMIT_SMI_CHECK); |
888 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 861 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
889 break; | 862 break; |
890 } | 863 } |
891 | 864 |
892 case VariableLocation::LOOKUP: { | 865 case VariableLocation::LOOKUP: { |
893 Comment cmnt(masm_, "[ Function Declaration"); | 866 Comment cmnt(masm_, "[ Function Declaration"); |
894 __ Mov(x2, Operand(variable->name())); | 867 __ Mov(x2, Operand(variable->name())); |
895 __ Push(x2); | 868 PushOperand(x2); |
896 // Push initial value for function declaration. | 869 // Push initial value for function declaration. |
897 VisitForStackValue(declaration->fun()); | 870 VisitForStackValue(declaration->fun()); |
898 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); | 871 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); |
899 __ CallRuntime(Runtime::kDeclareLookupSlot); | 872 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); |
900 break; | 873 break; |
901 } | 874 } |
902 } | 875 } |
903 } | 876 } |
904 | 877 |
905 | 878 |
906 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 879 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
907 // Call the runtime to declare the globals. | 880 // Call the runtime to declare the globals. |
908 __ Mov(x11, Operand(pairs)); | 881 __ Mov(x11, Operand(pairs)); |
909 Register flags = xzr; | 882 Register flags = xzr; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 __ Bind(&skip); | 960 __ Bind(&skip); |
988 | 961 |
989 __ Cbnz(x0, &next_test); | 962 __ Cbnz(x0, &next_test); |
990 __ Drop(1); // Switch value is no longer needed. | 963 __ Drop(1); // Switch value is no longer needed. |
991 __ B(clause->body_target()); | 964 __ B(clause->body_target()); |
992 } | 965 } |
993 | 966 |
994 // Discard the test value and jump to the default if present, otherwise to | 967 // Discard the test value and jump to the default if present, otherwise to |
995 // the end of the statement. | 968 // the end of the statement. |
996 __ Bind(&next_test); | 969 __ Bind(&next_test); |
997 __ Drop(1); // Switch value is no longer needed. | 970 DropOperands(1); // Switch value is no longer needed. |
998 if (default_clause == NULL) { | 971 if (default_clause == NULL) { |
999 __ B(nested_statement.break_label()); | 972 __ B(nested_statement.break_label()); |
1000 } else { | 973 } else { |
1001 __ B(default_clause->body_target()); | 974 __ B(default_clause->body_target()); |
1002 } | 975 } |
1003 | 976 |
1004 // Compile all the case bodies. | 977 // Compile all the case bodies. |
1005 for (int i = 0; i < clauses->length(); i++) { | 978 for (int i = 0; i < clauses->length(); i++) { |
1006 Comment cmnt(masm_, "[ Case body"); | 979 Comment cmnt(masm_, "[ Case body"); |
1007 CaseClause* clause = clauses->at(i); | 980 CaseClause* clause = clauses->at(i); |
(...skipping 16 matching lines...) Expand all Loading... |
1024 | 997 |
1025 // TODO(all): This visitor probably needs better comments and a revisit. | 998 // TODO(all): This visitor probably needs better comments and a revisit. |
1026 | 999 |
1027 Label loop, exit; | 1000 Label loop, exit; |
1028 ForIn loop_statement(this, stmt); | 1001 ForIn loop_statement(this, stmt); |
1029 increment_loop_depth(); | 1002 increment_loop_depth(); |
1030 | 1003 |
1031 // Get the object to enumerate over. | 1004 // Get the object to enumerate over. |
1032 SetExpressionAsStatementPosition(stmt->enumerable()); | 1005 SetExpressionAsStatementPosition(stmt->enumerable()); |
1033 VisitForAccumulatorValue(stmt->enumerable()); | 1006 VisitForAccumulatorValue(stmt->enumerable()); |
| 1007 OperandStackDepthIncrement(ForIn::kElementCount); |
1034 | 1008 |
1035 // If the object is null or undefined, skip over the loop, otherwise convert | 1009 // If the object is null or undefined, skip over the loop, otherwise convert |
1036 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 1010 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
1037 Label convert, done_convert; | 1011 Label convert, done_convert; |
1038 __ JumpIfSmi(x0, &convert); | 1012 __ JumpIfSmi(x0, &convert); |
1039 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); | 1013 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); |
1040 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); | 1014 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); |
1041 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); | 1015 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); |
1042 __ Bind(&convert); | 1016 __ Bind(&convert); |
1043 ToObjectStub stub(isolate()); | 1017 ToObjectStub stub(isolate()); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 // TODO(all): We could use a callee saved register to avoid popping. | 1149 // TODO(all): We could use a callee saved register to avoid popping. |
1176 __ Pop(x0); | 1150 __ Pop(x0); |
1177 __ Add(x0, x0, Smi::FromInt(1)); | 1151 __ Add(x0, x0, Smi::FromInt(1)); |
1178 __ Push(x0); | 1152 __ Push(x0); |
1179 | 1153 |
1180 EmitBackEdgeBookkeeping(stmt, &loop); | 1154 EmitBackEdgeBookkeeping(stmt, &loop); |
1181 __ B(&loop); | 1155 __ B(&loop); |
1182 | 1156 |
1183 // Remove the pointers stored on the stack. | 1157 // Remove the pointers stored on the stack. |
1184 __ Bind(loop_statement.break_label()); | 1158 __ Bind(loop_statement.break_label()); |
1185 __ Drop(5); | 1159 DropOperands(5); |
1186 | 1160 |
1187 // Exit and decrement the loop depth. | 1161 // Exit and decrement the loop depth. |
1188 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1162 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1189 __ Bind(&exit); | 1163 __ Bind(&exit); |
1190 decrement_loop_depth(); | 1164 decrement_loop_depth(); |
1191 } | 1165 } |
1192 | 1166 |
1193 | 1167 |
1194 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1168 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
1195 bool pretenure) { | 1169 bool pretenure) { |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1444 FastCloneRegExpStub stub(isolate()); | 1418 FastCloneRegExpStub stub(isolate()); |
1445 __ CallStub(&stub); | 1419 __ CallStub(&stub); |
1446 context()->Plug(x0); | 1420 context()->Plug(x0); |
1447 } | 1421 } |
1448 | 1422 |
1449 | 1423 |
1450 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { | 1424 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
1451 Expression* expression = (property == NULL) ? NULL : property->value(); | 1425 Expression* expression = (property == NULL) ? NULL : property->value(); |
1452 if (expression == NULL) { | 1426 if (expression == NULL) { |
1453 __ LoadRoot(x10, Heap::kNullValueRootIndex); | 1427 __ LoadRoot(x10, Heap::kNullValueRootIndex); |
1454 __ Push(x10); | 1428 PushOperand(x10); |
1455 } else { | 1429 } else { |
1456 VisitForStackValue(expression); | 1430 VisitForStackValue(expression); |
1457 if (NeedsHomeObject(expression)) { | 1431 if (NeedsHomeObject(expression)) { |
1458 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || | 1432 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
1459 property->kind() == ObjectLiteral::Property::SETTER); | 1433 property->kind() == ObjectLiteral::Property::SETTER); |
1460 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; | 1434 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
1461 EmitSetHomeObject(expression, offset, property->GetSlot()); | 1435 EmitSetHomeObject(expression, offset, property->GetSlot()); |
1462 } | 1436 } |
1463 } | 1437 } |
1464 } | 1438 } |
(...skipping 24 matching lines...) Expand all Loading... |
1489 AccessorTable accessor_table(zone()); | 1463 AccessorTable accessor_table(zone()); |
1490 int property_index = 0; | 1464 int property_index = 0; |
1491 for (; property_index < expr->properties()->length(); property_index++) { | 1465 for (; property_index < expr->properties()->length(); property_index++) { |
1492 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1466 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1493 if (property->is_computed_name()) break; | 1467 if (property->is_computed_name()) break; |
1494 if (property->IsCompileTimeValue()) continue; | 1468 if (property->IsCompileTimeValue()) continue; |
1495 | 1469 |
1496 Literal* key = property->key()->AsLiteral(); | 1470 Literal* key = property->key()->AsLiteral(); |
1497 Expression* value = property->value(); | 1471 Expression* value = property->value(); |
1498 if (!result_saved) { | 1472 if (!result_saved) { |
1499 __ Push(x0); // Save result on stack | 1473 PushOperand(x0); // Save result on stack |
1500 result_saved = true; | 1474 result_saved = true; |
1501 } | 1475 } |
1502 switch (property->kind()) { | 1476 switch (property->kind()) { |
1503 case ObjectLiteral::Property::CONSTANT: | 1477 case ObjectLiteral::Property::CONSTANT: |
1504 UNREACHABLE(); | 1478 UNREACHABLE(); |
1505 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1479 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1506 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1480 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1507 // Fall through. | 1481 // Fall through. |
1508 case ObjectLiteral::Property::COMPUTED: | 1482 case ObjectLiteral::Property::COMPUTED: |
1509 // It is safe to use [[Put]] here because the boilerplate already | 1483 // It is safe to use [[Put]] here because the boilerplate already |
(...skipping 10 matching lines...) Expand all Loading... |
1520 | 1494 |
1521 if (NeedsHomeObject(value)) { | 1495 if (NeedsHomeObject(value)) { |
1522 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); | 1496 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
1523 } | 1497 } |
1524 } else { | 1498 } else { |
1525 VisitForEffect(value); | 1499 VisitForEffect(value); |
1526 } | 1500 } |
1527 break; | 1501 break; |
1528 } | 1502 } |
1529 __ Peek(x0, 0); | 1503 __ Peek(x0, 0); |
1530 __ Push(x0); | 1504 PushOperand(x0); |
1531 VisitForStackValue(key); | 1505 VisitForStackValue(key); |
1532 VisitForStackValue(value); | 1506 VisitForStackValue(value); |
1533 if (property->emit_store()) { | 1507 if (property->emit_store()) { |
1534 if (NeedsHomeObject(value)) { | 1508 if (NeedsHomeObject(value)) { |
1535 EmitSetHomeObject(value, 2, property->GetSlot()); | 1509 EmitSetHomeObject(value, 2, property->GetSlot()); |
1536 } | 1510 } |
1537 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode | 1511 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode |
1538 __ Push(x0); | 1512 PushOperand(x0); |
1539 __ CallRuntime(Runtime::kSetProperty); | 1513 CallRuntimeWithOperands(Runtime::kSetProperty); |
1540 } else { | 1514 } else { |
1541 __ Drop(3); | 1515 DropOperands(3); |
1542 } | 1516 } |
1543 break; | 1517 break; |
1544 case ObjectLiteral::Property::PROTOTYPE: | 1518 case ObjectLiteral::Property::PROTOTYPE: |
1545 DCHECK(property->emit_store()); | 1519 DCHECK(property->emit_store()); |
1546 // Duplicate receiver on stack. | 1520 // Duplicate receiver on stack. |
1547 __ Peek(x0, 0); | 1521 __ Peek(x0, 0); |
1548 __ Push(x0); | 1522 PushOperand(x0); |
1549 VisitForStackValue(value); | 1523 VisitForStackValue(value); |
1550 __ CallRuntime(Runtime::kInternalSetPrototype); | 1524 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
1551 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1525 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
1552 NO_REGISTERS); | 1526 NO_REGISTERS); |
1553 break; | 1527 break; |
1554 case ObjectLiteral::Property::GETTER: | 1528 case ObjectLiteral::Property::GETTER: |
1555 if (property->emit_store()) { | 1529 if (property->emit_store()) { |
1556 accessor_table.lookup(key)->second->getter = property; | 1530 accessor_table.lookup(key)->second->getter = property; |
1557 } | 1531 } |
1558 break; | 1532 break; |
1559 case ObjectLiteral::Property::SETTER: | 1533 case ObjectLiteral::Property::SETTER: |
1560 if (property->emit_store()) { | 1534 if (property->emit_store()) { |
1561 accessor_table.lookup(key)->second->setter = property; | 1535 accessor_table.lookup(key)->second->setter = property; |
1562 } | 1536 } |
1563 break; | 1537 break; |
1564 } | 1538 } |
1565 } | 1539 } |
1566 | 1540 |
1567 // Emit code to define accessors, using only a single call to the runtime for | 1541 // Emit code to define accessors, using only a single call to the runtime for |
1568 // each pair of corresponding getters and setters. | 1542 // each pair of corresponding getters and setters. |
1569 for (AccessorTable::Iterator it = accessor_table.begin(); | 1543 for (AccessorTable::Iterator it = accessor_table.begin(); |
1570 it != accessor_table.end(); | 1544 it != accessor_table.end(); |
1571 ++it) { | 1545 ++it) { |
1572 __ Peek(x10, 0); // Duplicate receiver. | 1546 __ Peek(x10, 0); // Duplicate receiver. |
1573 __ Push(x10); | 1547 PushOperand(x10); |
1574 VisitForStackValue(it->first); | 1548 VisitForStackValue(it->first); |
1575 EmitAccessor(it->second->getter); | 1549 EmitAccessor(it->second->getter); |
1576 EmitAccessor(it->second->setter); | 1550 EmitAccessor(it->second->setter); |
1577 __ Mov(x10, Smi::FromInt(NONE)); | 1551 __ Mov(x10, Smi::FromInt(NONE)); |
1578 __ Push(x10); | 1552 PushOperand(x10); |
1579 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); | 1553 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); |
1580 } | 1554 } |
1581 | 1555 |
1582 // Object literals have two parts. The "static" part on the left contains no | 1556 // Object literals have two parts. The "static" part on the left contains no |
1583 // computed property names, and so we can compute its map ahead of time; see | 1557 // computed property names, and so we can compute its map ahead of time; see |
1584 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1558 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
1585 // starts with the first computed property name, and continues with all | 1559 // starts with the first computed property name, and continues with all |
1586 // properties to its right. All the code from above initializes the static | 1560 // properties to its right. All the code from above initializes the static |
1587 // component of the object literal, and arranges for the map of the result to | 1561 // component of the object literal, and arranges for the map of the result to |
1588 // reflect the static order in which the keys appear. For the dynamic | 1562 // reflect the static order in which the keys appear. For the dynamic |
1589 // properties, we compile them into a series of "SetOwnProperty" runtime | 1563 // properties, we compile them into a series of "SetOwnProperty" runtime |
1590 // calls. This will preserve insertion order. | 1564 // calls. This will preserve insertion order. |
1591 for (; property_index < expr->properties()->length(); property_index++) { | 1565 for (; property_index < expr->properties()->length(); property_index++) { |
1592 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1566 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1593 | 1567 |
1594 Expression* value = property->value(); | 1568 Expression* value = property->value(); |
1595 if (!result_saved) { | 1569 if (!result_saved) { |
1596 __ Push(x0); // Save result on stack | 1570 PushOperand(x0); // Save result on stack |
1597 result_saved = true; | 1571 result_saved = true; |
1598 } | 1572 } |
1599 | 1573 |
1600 __ Peek(x10, 0); // Duplicate receiver. | 1574 __ Peek(x10, 0); // Duplicate receiver. |
1601 __ Push(x10); | 1575 PushOperand(x10); |
1602 | 1576 |
1603 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1577 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
1604 DCHECK(!property->is_computed_name()); | 1578 DCHECK(!property->is_computed_name()); |
1605 VisitForStackValue(value); | 1579 VisitForStackValue(value); |
1606 DCHECK(property->emit_store()); | 1580 DCHECK(property->emit_store()); |
1607 __ CallRuntime(Runtime::kInternalSetPrototype); | 1581 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
1608 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1582 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
1609 NO_REGISTERS); | 1583 NO_REGISTERS); |
1610 } else { | 1584 } else { |
1611 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); | 1585 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); |
1612 VisitForStackValue(value); | 1586 VisitForStackValue(value); |
1613 if (NeedsHomeObject(value)) { | 1587 if (NeedsHomeObject(value)) { |
1614 EmitSetHomeObject(value, 2, property->GetSlot()); | 1588 EmitSetHomeObject(value, 2, property->GetSlot()); |
1615 } | 1589 } |
1616 | 1590 |
1617 switch (property->kind()) { | 1591 switch (property->kind()) { |
1618 case ObjectLiteral::Property::CONSTANT: | 1592 case ObjectLiteral::Property::CONSTANT: |
1619 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1593 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1620 case ObjectLiteral::Property::COMPUTED: | 1594 case ObjectLiteral::Property::COMPUTED: |
1621 if (property->emit_store()) { | 1595 if (property->emit_store()) { |
1622 __ Push(Smi::FromInt(NONE)); | 1596 PushOperand(Smi::FromInt(NONE)); |
1623 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 1597 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
1624 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 1598 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
1625 } else { | 1599 } else { |
1626 __ Drop(3); | 1600 DropOperands(3); |
1627 } | 1601 } |
1628 break; | 1602 break; |
1629 | 1603 |
1630 case ObjectLiteral::Property::PROTOTYPE: | 1604 case ObjectLiteral::Property::PROTOTYPE: |
1631 UNREACHABLE(); | 1605 UNREACHABLE(); |
1632 break; | 1606 break; |
1633 | 1607 |
1634 case ObjectLiteral::Property::GETTER: | 1608 case ObjectLiteral::Property::GETTER: |
1635 __ Push(Smi::FromInt(NONE)); | 1609 PushOperand(Smi::FromInt(NONE)); |
1636 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 1610 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
1637 break; | 1611 break; |
1638 | 1612 |
1639 case ObjectLiteral::Property::SETTER: | 1613 case ObjectLiteral::Property::SETTER: |
1640 __ Push(Smi::FromInt(NONE)); | 1614 PushOperand(Smi::FromInt(NONE)); |
1641 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 1615 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
1642 break; | 1616 break; |
1643 } | 1617 } |
1644 } | 1618 } |
1645 } | 1619 } |
1646 | 1620 |
1647 if (expr->has_function()) { | 1621 if (expr->has_function()) { |
1648 DCHECK(result_saved); | 1622 DCHECK(result_saved); |
1649 __ Peek(x0, 0); | 1623 __ Peek(x0, 0); |
1650 __ Push(x0); | 1624 __ Push(x0); |
1651 __ CallRuntime(Runtime::kToFastProperties); | 1625 __ CallRuntime(Runtime::kToFastProperties); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 int array_index = 0; | 1669 int array_index = 0; |
1696 for (; array_index < length; array_index++) { | 1670 for (; array_index < length; array_index++) { |
1697 Expression* subexpr = subexprs->at(array_index); | 1671 Expression* subexpr = subexprs->at(array_index); |
1698 DCHECK(!subexpr->IsSpread()); | 1672 DCHECK(!subexpr->IsSpread()); |
1699 | 1673 |
1700 // If the subexpression is a literal or a simple materialized literal it | 1674 // If the subexpression is a literal or a simple materialized literal it |
1701 // is already set in the cloned array. | 1675 // is already set in the cloned array. |
1702 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1676 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1703 | 1677 |
1704 if (!result_saved) { | 1678 if (!result_saved) { |
1705 __ Push(x0); | 1679 PushOperand(x0); |
1706 result_saved = true; | 1680 result_saved = true; |
1707 } | 1681 } |
1708 VisitForAccumulatorValue(subexpr); | 1682 VisitForAccumulatorValue(subexpr); |
1709 | 1683 |
1710 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); | 1684 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); |
1711 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1685 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
1712 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); | 1686 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); |
1713 Handle<Code> ic = | 1687 Handle<Code> ic = |
1714 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 1688 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
1715 CallIC(ic); | 1689 CallIC(ic); |
1716 | 1690 |
1717 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1691 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
1718 } | 1692 } |
1719 | 1693 |
1720 // In case the array literal contains spread expressions it has two parts. The | 1694 // In case the array literal contains spread expressions it has two parts. The |
1721 // first part is the "static" array which has a literal index is handled | 1695 // first part is the "static" array which has a literal index is handled |
1722 // above. The second part is the part after the first spread expression | 1696 // above. The second part is the part after the first spread expression |
1723 // (inclusive) and these elements gets appended to the array. Note that the | 1697 // (inclusive) and these elements gets appended to the array. Note that the |
1724 // number elements an iterable produces is unknown ahead of time. | 1698 // number elements an iterable produces is unknown ahead of time. |
1725 if (array_index < length && result_saved) { | 1699 if (array_index < length && result_saved) { |
1726 __ Pop(x0); | 1700 PopOperand(x0); |
1727 result_saved = false; | 1701 result_saved = false; |
1728 } | 1702 } |
1729 for (; array_index < length; array_index++) { | 1703 for (; array_index < length; array_index++) { |
1730 Expression* subexpr = subexprs->at(array_index); | 1704 Expression* subexpr = subexprs->at(array_index); |
1731 | 1705 |
1732 __ Push(x0); | 1706 PushOperand(x0); |
1733 DCHECK(!subexpr->IsSpread()); | 1707 DCHECK(!subexpr->IsSpread()); |
1734 VisitForStackValue(subexpr); | 1708 VisitForStackValue(subexpr); |
1735 __ CallRuntime(Runtime::kAppendElement); | 1709 CallRuntimeWithOperands(Runtime::kAppendElement); |
1736 | 1710 |
1737 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1711 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
1738 } | 1712 } |
1739 | 1713 |
1740 if (result_saved) { | 1714 if (result_saved) { |
1741 context()->PlugTOS(); | 1715 context()->PlugTOS(); |
1742 } else { | 1716 } else { |
1743 context()->Plug(x0); | 1717 context()->Plug(x0); |
1744 } | 1718 } |
1745 } | 1719 } |
(...skipping 20 matching lines...) Expand all Loading... |
1766 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 1740 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
1767 } else { | 1741 } else { |
1768 VisitForStackValue(property->obj()); | 1742 VisitForStackValue(property->obj()); |
1769 } | 1743 } |
1770 break; | 1744 break; |
1771 case NAMED_SUPER_PROPERTY: | 1745 case NAMED_SUPER_PROPERTY: |
1772 VisitForStackValue( | 1746 VisitForStackValue( |
1773 property->obj()->AsSuperPropertyReference()->this_var()); | 1747 property->obj()->AsSuperPropertyReference()->this_var()); |
1774 VisitForAccumulatorValue( | 1748 VisitForAccumulatorValue( |
1775 property->obj()->AsSuperPropertyReference()->home_object()); | 1749 property->obj()->AsSuperPropertyReference()->home_object()); |
1776 __ Push(result_register()); | 1750 PushOperand(result_register()); |
1777 if (expr->is_compound()) { | 1751 if (expr->is_compound()) { |
1778 const Register scratch = x10; | 1752 const Register scratch = x10; |
1779 __ Peek(scratch, kPointerSize); | 1753 __ Peek(scratch, kPointerSize); |
1780 __ Push(scratch, result_register()); | 1754 PushOperands(scratch, result_register()); |
1781 } | 1755 } |
1782 break; | 1756 break; |
1783 case KEYED_SUPER_PROPERTY: | 1757 case KEYED_SUPER_PROPERTY: |
1784 VisitForStackValue( | 1758 VisitForStackValue( |
1785 property->obj()->AsSuperPropertyReference()->this_var()); | 1759 property->obj()->AsSuperPropertyReference()->this_var()); |
1786 VisitForStackValue( | 1760 VisitForStackValue( |
1787 property->obj()->AsSuperPropertyReference()->home_object()); | 1761 property->obj()->AsSuperPropertyReference()->home_object()); |
1788 VisitForAccumulatorValue(property->key()); | 1762 VisitForAccumulatorValue(property->key()); |
1789 __ Push(result_register()); | 1763 PushOperand(result_register()); |
1790 if (expr->is_compound()) { | 1764 if (expr->is_compound()) { |
1791 const Register scratch1 = x10; | 1765 const Register scratch1 = x10; |
1792 const Register scratch2 = x11; | 1766 const Register scratch2 = x11; |
1793 __ Peek(scratch1, 2 * kPointerSize); | 1767 __ Peek(scratch1, 2 * kPointerSize); |
1794 __ Peek(scratch2, kPointerSize); | 1768 __ Peek(scratch2, kPointerSize); |
1795 __ Push(scratch1, scratch2, result_register()); | 1769 PushOperands(scratch1, scratch2, result_register()); |
1796 } | 1770 } |
1797 break; | 1771 break; |
1798 case KEYED_PROPERTY: | 1772 case KEYED_PROPERTY: |
1799 if (expr->is_compound()) { | 1773 if (expr->is_compound()) { |
1800 VisitForStackValue(property->obj()); | 1774 VisitForStackValue(property->obj()); |
1801 VisitForStackValue(property->key()); | 1775 VisitForStackValue(property->key()); |
1802 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); | 1776 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
1803 __ Peek(LoadDescriptor::NameRegister(), 0); | 1777 __ Peek(LoadDescriptor::NameRegister(), 0); |
1804 } else { | 1778 } else { |
1805 VisitForStackValue(property->obj()); | 1779 VisitForStackValue(property->obj()); |
(...skipping 24 matching lines...) Expand all Loading... |
1830 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1804 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1831 break; | 1805 break; |
1832 case KEYED_PROPERTY: | 1806 case KEYED_PROPERTY: |
1833 EmitKeyedPropertyLoad(property); | 1807 EmitKeyedPropertyLoad(property); |
1834 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1808 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1835 break; | 1809 break; |
1836 } | 1810 } |
1837 } | 1811 } |
1838 | 1812 |
1839 Token::Value op = expr->binary_op(); | 1813 Token::Value op = expr->binary_op(); |
1840 __ Push(x0); // Left operand goes on the stack. | 1814 PushOperand(x0); // Left operand goes on the stack. |
1841 VisitForAccumulatorValue(expr->value()); | 1815 VisitForAccumulatorValue(expr->value()); |
1842 | 1816 |
1843 AccumulatorValueContext context(this); | 1817 AccumulatorValueContext context(this); |
1844 if (ShouldInlineSmiCase(op)) { | 1818 if (ShouldInlineSmiCase(op)) { |
1845 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1819 EmitInlineSmiBinaryOp(expr->binary_operation(), |
1846 op, | 1820 op, |
1847 expr->target(), | 1821 expr->target(), |
1848 expr->value()); | 1822 expr->value()); |
1849 } else { | 1823 } else { |
1850 EmitBinaryOp(expr->binary_operation(), op); | 1824 EmitBinaryOp(expr->binary_operation(), op); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1889 Literal* key = prop->key()->AsLiteral(); | 1863 Literal* key = prop->key()->AsLiteral(); |
1890 DCHECK(!prop->IsSuperAccess()); | 1864 DCHECK(!prop->IsSuperAccess()); |
1891 | 1865 |
1892 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); | 1866 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); |
1893 __ Mov(LoadDescriptor::SlotRegister(), | 1867 __ Mov(LoadDescriptor::SlotRegister(), |
1894 SmiFromSlot(prop->PropertyFeedbackSlot())); | 1868 SmiFromSlot(prop->PropertyFeedbackSlot())); |
1895 CallLoadIC(NOT_INSIDE_TYPEOF); | 1869 CallLoadIC(NOT_INSIDE_TYPEOF); |
1896 } | 1870 } |
1897 | 1871 |
1898 | 1872 |
1899 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | |
1900 // Stack: receiver, home_object. | |
1901 SetExpressionPosition(prop); | |
1902 Literal* key = prop->key()->AsLiteral(); | |
1903 DCHECK(!key->value()->IsSmi()); | |
1904 DCHECK(prop->IsSuperAccess()); | |
1905 | |
1906 __ Push(key->value()); | |
1907 __ CallRuntime(Runtime::kLoadFromSuper); | |
1908 } | |
1909 | |
1910 | |
1911 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | |
1912 SetExpressionPosition(prop); | |
1913 // Call keyed load IC. It has arguments key and receiver in x0 and x1. | |
1914 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | |
1915 __ Mov(LoadDescriptor::SlotRegister(), | |
1916 SmiFromSlot(prop->PropertyFeedbackSlot())); | |
1917 CallIC(ic); | |
1918 } | |
1919 | |
1920 | |
1921 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | |
1922 // Stack: receiver, home_object, key. | |
1923 SetExpressionPosition(prop); | |
1924 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | |
1925 } | |
1926 | |
1927 | |
1928 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1873 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1929 Token::Value op, | 1874 Token::Value op, |
1930 Expression* left_expr, | 1875 Expression* left_expr, |
1931 Expression* right_expr) { | 1876 Expression* right_expr) { |
1932 Label done, both_smis, stub_call; | 1877 Label done, both_smis, stub_call; |
1933 | 1878 |
1934 // Get the arguments. | 1879 // Get the arguments. |
1935 Register left = x1; | 1880 Register left = x1; |
1936 Register right = x0; | 1881 Register right = x0; |
1937 Register result = x0; | 1882 Register result = x0; |
1938 __ Pop(left); | 1883 PopOperand(left); |
1939 | 1884 |
1940 // Perform combined smi check on both operands. | 1885 // Perform combined smi check on both operands. |
1941 __ Orr(x10, left, right); | 1886 __ Orr(x10, left, right); |
1942 JumpPatchSite patch_site(masm_); | 1887 JumpPatchSite patch_site(masm_); |
1943 patch_site.EmitJumpIfSmi(x10, &both_smis); | 1888 patch_site.EmitJumpIfSmi(x10, &both_smis); |
1944 | 1889 |
1945 __ Bind(&stub_call); | 1890 __ Bind(&stub_call); |
1946 | 1891 |
1947 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 1892 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
1948 { | 1893 { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2018 default: | 1963 default: |
2019 UNREACHABLE(); | 1964 UNREACHABLE(); |
2020 } | 1965 } |
2021 | 1966 |
2022 __ Bind(&done); | 1967 __ Bind(&done); |
2023 context()->Plug(x0); | 1968 context()->Plug(x0); |
2024 } | 1969 } |
2025 | 1970 |
2026 | 1971 |
2027 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { | 1972 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { |
2028 __ Pop(x1); | 1973 PopOperand(x1); |
2029 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 1974 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
2030 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. | 1975 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. |
2031 { | 1976 { |
2032 Assembler::BlockPoolsScope scope(masm_); | 1977 Assembler::BlockPoolsScope scope(masm_); |
2033 CallIC(code, expr->BinaryOperationFeedbackId()); | 1978 CallIC(code, expr->BinaryOperationFeedbackId()); |
2034 patch_site.EmitPatchInfo(); | 1979 patch_site.EmitPatchInfo(); |
2035 } | 1980 } |
2036 context()->Plug(x0); | 1981 context()->Plug(x0); |
2037 } | 1982 } |
2038 | 1983 |
2039 | 1984 |
2040 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { | 1985 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
2041 for (int i = 0; i < lit->properties()->length(); i++) { | 1986 for (int i = 0; i < lit->properties()->length(); i++) { |
2042 ObjectLiteral::Property* property = lit->properties()->at(i); | 1987 ObjectLiteral::Property* property = lit->properties()->at(i); |
2043 Expression* value = property->value(); | 1988 Expression* value = property->value(); |
2044 | 1989 |
2045 Register scratch = x1; | 1990 Register scratch = x1; |
2046 if (property->is_static()) { | 1991 if (property->is_static()) { |
2047 __ Peek(scratch, kPointerSize); // constructor | 1992 __ Peek(scratch, kPointerSize); // constructor |
2048 } else { | 1993 } else { |
2049 __ Peek(scratch, 0); // prototype | 1994 __ Peek(scratch, 0); // prototype |
2050 } | 1995 } |
2051 __ Push(scratch); | 1996 PushOperand(scratch); |
2052 EmitPropertyKey(property, lit->GetIdForProperty(i)); | 1997 EmitPropertyKey(property, lit->GetIdForProperty(i)); |
2053 | 1998 |
2054 // The static prototype property is read only. We handle the non computed | 1999 // The static prototype property is read only. We handle the non computed |
2055 // property name case in the parser. Since this is the only case where we | 2000 // property name case in the parser. Since this is the only case where we |
2056 // need to check for an own read only property we special case this so we do | 2001 // need to check for an own read only property we special case this so we do |
2057 // not need to do this for every property. | 2002 // not need to do this for every property. |
2058 if (property->is_static() && property->is_computed_name()) { | 2003 if (property->is_static() && property->is_computed_name()) { |
2059 __ CallRuntime(Runtime::kThrowIfStaticPrototype); | 2004 __ CallRuntime(Runtime::kThrowIfStaticPrototype); |
2060 __ Push(x0); | 2005 __ Push(x0); |
2061 } | 2006 } |
2062 | 2007 |
2063 VisitForStackValue(value); | 2008 VisitForStackValue(value); |
2064 if (NeedsHomeObject(value)) { | 2009 if (NeedsHomeObject(value)) { |
2065 EmitSetHomeObject(value, 2, property->GetSlot()); | 2010 EmitSetHomeObject(value, 2, property->GetSlot()); |
2066 } | 2011 } |
2067 | 2012 |
2068 switch (property->kind()) { | 2013 switch (property->kind()) { |
2069 case ObjectLiteral::Property::CONSTANT: | 2014 case ObjectLiteral::Property::CONSTANT: |
2070 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2015 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
2071 case ObjectLiteral::Property::PROTOTYPE: | 2016 case ObjectLiteral::Property::PROTOTYPE: |
2072 UNREACHABLE(); | 2017 UNREACHABLE(); |
2073 case ObjectLiteral::Property::COMPUTED: | 2018 case ObjectLiteral::Property::COMPUTED: |
2074 __ Push(Smi::FromInt(DONT_ENUM)); | 2019 PushOperand(Smi::FromInt(DONT_ENUM)); |
2075 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 2020 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
2076 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 2021 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
2077 break; | 2022 break; |
2078 | 2023 |
2079 case ObjectLiteral::Property::GETTER: | 2024 case ObjectLiteral::Property::GETTER: |
2080 __ Push(Smi::FromInt(DONT_ENUM)); | 2025 PushOperand(Smi::FromInt(DONT_ENUM)); |
2081 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 2026 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
2082 break; | 2027 break; |
2083 | 2028 |
2084 case ObjectLiteral::Property::SETTER: | 2029 case ObjectLiteral::Property::SETTER: |
2085 __ Push(Smi::FromInt(DONT_ENUM)); | 2030 PushOperand(Smi::FromInt(DONT_ENUM)); |
2086 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 2031 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
2087 break; | 2032 break; |
2088 | 2033 |
2089 default: | 2034 default: |
2090 UNREACHABLE(); | 2035 UNREACHABLE(); |
2091 } | 2036 } |
2092 } | 2037 } |
2093 } | 2038 } |
2094 | 2039 |
2095 | 2040 |
2096 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2041 void FullCodeGenerator::EmitAssignment(Expression* expr, |
2097 FeedbackVectorSlot slot) { | 2042 FeedbackVectorSlot slot) { |
2098 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 2043 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2099 | 2044 |
2100 Property* prop = expr->AsProperty(); | 2045 Property* prop = expr->AsProperty(); |
2101 LhsKind assign_type = Property::GetAssignType(prop); | 2046 LhsKind assign_type = Property::GetAssignType(prop); |
2102 | 2047 |
2103 switch (assign_type) { | 2048 switch (assign_type) { |
2104 case VARIABLE: { | 2049 case VARIABLE: { |
2105 Variable* var = expr->AsVariableProxy()->var(); | 2050 Variable* var = expr->AsVariableProxy()->var(); |
2106 EffectContext context(this); | 2051 EffectContext context(this); |
2107 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2052 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2108 break; | 2053 break; |
2109 } | 2054 } |
2110 case NAMED_PROPERTY: { | 2055 case NAMED_PROPERTY: { |
2111 __ Push(x0); // Preserve value. | 2056 PushOperand(x0); // Preserve value. |
2112 VisitForAccumulatorValue(prop->obj()); | 2057 VisitForAccumulatorValue(prop->obj()); |
2113 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid | 2058 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid |
2114 // this copy. | 2059 // this copy. |
2115 __ Mov(StoreDescriptor::ReceiverRegister(), x0); | 2060 __ Mov(StoreDescriptor::ReceiverRegister(), x0); |
2116 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. | 2061 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
2117 __ Mov(StoreDescriptor::NameRegister(), | 2062 __ Mov(StoreDescriptor::NameRegister(), |
2118 Operand(prop->key()->AsLiteral()->value())); | 2063 Operand(prop->key()->AsLiteral()->value())); |
2119 EmitLoadStoreICSlot(slot); | 2064 EmitLoadStoreICSlot(slot); |
2120 CallStoreIC(); | 2065 CallStoreIC(); |
2121 break; | 2066 break; |
2122 } | 2067 } |
2123 case NAMED_SUPER_PROPERTY: { | 2068 case NAMED_SUPER_PROPERTY: { |
2124 __ Push(x0); | 2069 PushOperand(x0); |
2125 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2070 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2126 VisitForAccumulatorValue( | 2071 VisitForAccumulatorValue( |
2127 prop->obj()->AsSuperPropertyReference()->home_object()); | 2072 prop->obj()->AsSuperPropertyReference()->home_object()); |
2128 // stack: value, this; x0: home_object | 2073 // stack: value, this; x0: home_object |
2129 Register scratch = x10; | 2074 Register scratch = x10; |
2130 Register scratch2 = x11; | 2075 Register scratch2 = x11; |
2131 __ mov(scratch, result_register()); // home_object | 2076 __ mov(scratch, result_register()); // home_object |
2132 __ Peek(x0, kPointerSize); // value | 2077 __ Peek(x0, kPointerSize); // value |
2133 __ Peek(scratch2, 0); // this | 2078 __ Peek(scratch2, 0); // this |
2134 __ Poke(scratch2, kPointerSize); // this | 2079 __ Poke(scratch2, kPointerSize); // this |
2135 __ Poke(scratch, 0); // home_object | 2080 __ Poke(scratch, 0); // home_object |
2136 // stack: this, home_object; x0: value | 2081 // stack: this, home_object; x0: value |
2137 EmitNamedSuperPropertyStore(prop); | 2082 EmitNamedSuperPropertyStore(prop); |
2138 break; | 2083 break; |
2139 } | 2084 } |
2140 case KEYED_SUPER_PROPERTY: { | 2085 case KEYED_SUPER_PROPERTY: { |
2141 __ Push(x0); | 2086 PushOperand(x0); |
2142 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2087 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2143 VisitForStackValue( | 2088 VisitForStackValue( |
2144 prop->obj()->AsSuperPropertyReference()->home_object()); | 2089 prop->obj()->AsSuperPropertyReference()->home_object()); |
2145 VisitForAccumulatorValue(prop->key()); | 2090 VisitForAccumulatorValue(prop->key()); |
2146 Register scratch = x10; | 2091 Register scratch = x10; |
2147 Register scratch2 = x11; | 2092 Register scratch2 = x11; |
2148 __ Peek(scratch2, 2 * kPointerSize); // value | 2093 __ Peek(scratch2, 2 * kPointerSize); // value |
2149 // stack: value, this, home_object; x0: key, x11: value | 2094 // stack: value, this, home_object; x0: key, x11: value |
2150 __ Peek(scratch, kPointerSize); // this | 2095 __ Peek(scratch, kPointerSize); // this |
2151 __ Poke(scratch, 2 * kPointerSize); | 2096 __ Poke(scratch, 2 * kPointerSize); |
2152 __ Peek(scratch, 0); // home_object | 2097 __ Peek(scratch, 0); // home_object |
2153 __ Poke(scratch, kPointerSize); | 2098 __ Poke(scratch, kPointerSize); |
2154 __ Poke(x0, 0); | 2099 __ Poke(x0, 0); |
2155 __ Move(x0, scratch2); | 2100 __ Move(x0, scratch2); |
2156 // stack: this, home_object, key; x0: value. | 2101 // stack: this, home_object, key; x0: value. |
2157 EmitKeyedSuperPropertyStore(prop); | 2102 EmitKeyedSuperPropertyStore(prop); |
2158 break; | 2103 break; |
2159 } | 2104 } |
2160 case KEYED_PROPERTY: { | 2105 case KEYED_PROPERTY: { |
2161 __ Push(x0); // Preserve value. | 2106 PushOperand(x0); // Preserve value. |
2162 VisitForStackValue(prop->obj()); | 2107 VisitForStackValue(prop->obj()); |
2163 VisitForAccumulatorValue(prop->key()); | 2108 VisitForAccumulatorValue(prop->key()); |
2164 __ Mov(StoreDescriptor::NameRegister(), x0); | 2109 __ Mov(StoreDescriptor::NameRegister(), x0); |
2165 __ Pop(StoreDescriptor::ReceiverRegister(), | 2110 PopOperands(StoreDescriptor::ReceiverRegister(), |
2166 StoreDescriptor::ValueRegister()); | 2111 StoreDescriptor::ValueRegister()); |
2167 EmitLoadStoreICSlot(slot); | 2112 EmitLoadStoreICSlot(slot); |
2168 Handle<Code> ic = | 2113 Handle<Code> ic = |
2169 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2114 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2170 CallIC(ic); | 2115 CallIC(ic); |
2171 break; | 2116 break; |
2172 } | 2117 } |
2173 } | 2118 } |
2174 context()->Plug(x0); | 2119 context()->Plug(x0); |
2175 } | 2120 } |
2176 | 2121 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2291 | 2236 |
2292 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2237 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2293 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 2238 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); |
2294 // Assignment to a property, using a named store IC. | 2239 // Assignment to a property, using a named store IC. |
2295 Property* prop = expr->target()->AsProperty(); | 2240 Property* prop = expr->target()->AsProperty(); |
2296 DCHECK(prop != NULL); | 2241 DCHECK(prop != NULL); |
2297 DCHECK(prop->key()->IsLiteral()); | 2242 DCHECK(prop->key()->IsLiteral()); |
2298 | 2243 |
2299 __ Mov(StoreDescriptor::NameRegister(), | 2244 __ Mov(StoreDescriptor::NameRegister(), |
2300 Operand(prop->key()->AsLiteral()->value())); | 2245 Operand(prop->key()->AsLiteral()->value())); |
2301 __ Pop(StoreDescriptor::ReceiverRegister()); | 2246 PopOperand(StoreDescriptor::ReceiverRegister()); |
2302 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2247 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2303 CallStoreIC(); | 2248 CallStoreIC(); |
2304 | 2249 |
2305 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2250 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2306 context()->Plug(x0); | 2251 context()->Plug(x0); |
2307 } | 2252 } |
2308 | 2253 |
2309 | 2254 |
2310 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2255 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2311 // Assignment to named property of super. | 2256 // Assignment to named property of super. |
2312 // x0 : value | 2257 // x0 : value |
2313 // stack : receiver ('this'), home_object | 2258 // stack : receiver ('this'), home_object |
2314 DCHECK(prop != NULL); | 2259 DCHECK(prop != NULL); |
2315 Literal* key = prop->key()->AsLiteral(); | 2260 Literal* key = prop->key()->AsLiteral(); |
2316 DCHECK(key != NULL); | 2261 DCHECK(key != NULL); |
2317 | 2262 |
2318 __ Push(key->value()); | 2263 PushOperand(key->value()); |
2319 __ Push(x0); | 2264 PushOperand(x0); |
2320 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict | 2265 CallRuntimeWithOperands(is_strict(language_mode()) |
2321 : Runtime::kStoreToSuper_Sloppy)); | 2266 ? Runtime::kStoreToSuper_Strict |
| 2267 : Runtime::kStoreToSuper_Sloppy); |
2322 } | 2268 } |
2323 | 2269 |
2324 | 2270 |
2325 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | 2271 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { |
2326 // Assignment to named property of super. | 2272 // Assignment to named property of super. |
2327 // x0 : value | 2273 // x0 : value |
2328 // stack : receiver ('this'), home_object, key | 2274 // stack : receiver ('this'), home_object, key |
2329 DCHECK(prop != NULL); | 2275 DCHECK(prop != NULL); |
2330 | 2276 |
2331 __ Push(x0); | 2277 PushOperand(x0); |
2332 __ CallRuntime((is_strict(language_mode()) | 2278 CallRuntimeWithOperands(is_strict(language_mode()) |
2333 ? Runtime::kStoreKeyedToSuper_Strict | 2279 ? Runtime::kStoreKeyedToSuper_Strict |
2334 : Runtime::kStoreKeyedToSuper_Sloppy)); | 2280 : Runtime::kStoreKeyedToSuper_Sloppy); |
2335 } | 2281 } |
2336 | 2282 |
2337 | 2283 |
2338 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2284 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2339 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 2285 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
2340 // Assignment to a property, using a keyed store IC. | 2286 // Assignment to a property, using a keyed store IC. |
2341 | 2287 |
2342 // TODO(all): Could we pass this in registers rather than on the stack? | 2288 // TODO(all): Could we pass this in registers rather than on the stack? |
2343 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); | 2289 PopOperands(StoreDescriptor::NameRegister(), |
| 2290 StoreDescriptor::ReceiverRegister()); |
2344 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 2291 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
2345 | 2292 |
2346 Handle<Code> ic = | 2293 Handle<Code> ic = |
2347 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2294 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2348 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2295 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2349 CallIC(ic); | 2296 CallIC(ic); |
2350 | 2297 |
2351 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2298 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2352 context()->Plug(x0); | 2299 context()->Plug(x0); |
2353 } | 2300 } |
(...skipping 13 matching lines...) Expand all Loading... |
2367 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2314 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2368 VisitForStackValue( | 2315 VisitForStackValue( |
2369 expr->obj()->AsSuperPropertyReference()->home_object()); | 2316 expr->obj()->AsSuperPropertyReference()->home_object()); |
2370 EmitNamedSuperPropertyLoad(expr); | 2317 EmitNamedSuperPropertyLoad(expr); |
2371 } | 2318 } |
2372 } else { | 2319 } else { |
2373 if (!expr->IsSuperAccess()) { | 2320 if (!expr->IsSuperAccess()) { |
2374 VisitForStackValue(expr->obj()); | 2321 VisitForStackValue(expr->obj()); |
2375 VisitForAccumulatorValue(expr->key()); | 2322 VisitForAccumulatorValue(expr->key()); |
2376 __ Move(LoadDescriptor::NameRegister(), x0); | 2323 __ Move(LoadDescriptor::NameRegister(), x0); |
2377 __ Pop(LoadDescriptor::ReceiverRegister()); | 2324 PopOperand(LoadDescriptor::ReceiverRegister()); |
2378 EmitKeyedPropertyLoad(expr); | 2325 EmitKeyedPropertyLoad(expr); |
2379 } else { | 2326 } else { |
2380 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2327 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2381 VisitForStackValue( | 2328 VisitForStackValue( |
2382 expr->obj()->AsSuperPropertyReference()->home_object()); | 2329 expr->obj()->AsSuperPropertyReference()->home_object()); |
2383 VisitForStackValue(expr->key()); | 2330 VisitForStackValue(expr->key()); |
2384 EmitKeyedSuperPropertyLoad(expr); | 2331 EmitKeyedSuperPropertyLoad(expr); |
2385 } | 2332 } |
2386 } | 2333 } |
2387 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2334 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
(...skipping 21 matching lines...) Expand all Loading... |
2409 { StackValueContext context(this); | 2356 { StackValueContext context(this); |
2410 EmitVariableLoad(callee->AsVariableProxy()); | 2357 EmitVariableLoad(callee->AsVariableProxy()); |
2411 PrepareForBailout(callee, NO_REGISTERS); | 2358 PrepareForBailout(callee, NO_REGISTERS); |
2412 } | 2359 } |
2413 // Push undefined as receiver. This is patched in the method prologue if it | 2360 // Push undefined as receiver. This is patched in the method prologue if it |
2414 // is a sloppy mode method. | 2361 // is a sloppy mode method. |
2415 { | 2362 { |
2416 UseScratchRegisterScope temps(masm_); | 2363 UseScratchRegisterScope temps(masm_); |
2417 Register temp = temps.AcquireX(); | 2364 Register temp = temps.AcquireX(); |
2418 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); | 2365 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); |
2419 __ Push(temp); | 2366 PushOperand(temp); |
2420 } | 2367 } |
2421 convert_mode = ConvertReceiverMode::kNullOrUndefined; | 2368 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
2422 } else { | 2369 } else { |
2423 // Load the function from the receiver. | 2370 // Load the function from the receiver. |
2424 DCHECK(callee->IsProperty()); | 2371 DCHECK(callee->IsProperty()); |
2425 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2372 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2426 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2373 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
2427 EmitNamedPropertyLoad(callee->AsProperty()); | 2374 EmitNamedPropertyLoad(callee->AsProperty()); |
2428 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2375 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2429 // Push the target function under the receiver. | 2376 // Push the target function under the receiver. |
2430 __ Pop(x10); | 2377 PopOperand(x10); |
2431 __ Push(x0, x10); | 2378 PushOperands(x0, x10); |
2432 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 2379 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
2433 } | 2380 } |
2434 | 2381 |
2435 EmitCall(expr, convert_mode); | 2382 EmitCall(expr, convert_mode); |
2436 } | 2383 } |
2437 | 2384 |
2438 | 2385 |
2439 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2386 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2440 ASM_LOCATION("FullCodeGenerator::EmitSuperCallWithLoadIC"); | 2387 ASM_LOCATION("FullCodeGenerator::EmitSuperCallWithLoadIC"); |
2441 Expression* callee = expr->expression(); | 2388 Expression* callee = expr->expression(); |
2442 DCHECK(callee->IsProperty()); | 2389 DCHECK(callee->IsProperty()); |
2443 Property* prop = callee->AsProperty(); | 2390 Property* prop = callee->AsProperty(); |
2444 DCHECK(prop->IsSuperAccess()); | 2391 DCHECK(prop->IsSuperAccess()); |
2445 SetExpressionPosition(prop); | 2392 SetExpressionPosition(prop); |
2446 | 2393 |
2447 Literal* key = prop->key()->AsLiteral(); | 2394 Literal* key = prop->key()->AsLiteral(); |
2448 DCHECK(!key->value()->IsSmi()); | 2395 DCHECK(!key->value()->IsSmi()); |
2449 | 2396 |
2450 // Load the function from the receiver. | 2397 // Load the function from the receiver. |
2451 const Register scratch = x10; | 2398 const Register scratch = x10; |
2452 SuperPropertyReference* super_ref = | 2399 SuperPropertyReference* super_ref = |
2453 callee->AsProperty()->obj()->AsSuperPropertyReference(); | 2400 callee->AsProperty()->obj()->AsSuperPropertyReference(); |
2454 VisitForStackValue(super_ref->home_object()); | 2401 VisitForStackValue(super_ref->home_object()); |
2455 VisitForAccumulatorValue(super_ref->this_var()); | 2402 VisitForAccumulatorValue(super_ref->this_var()); |
2456 __ Push(x0); | 2403 PushOperand(x0); |
2457 __ Peek(scratch, kPointerSize); | 2404 __ Peek(scratch, kPointerSize); |
2458 __ Push(x0, scratch); | 2405 PushOperands(x0, scratch); |
2459 __ Push(key->value()); | 2406 PushOperand(key->value()); |
2460 | 2407 |
2461 // Stack here: | 2408 // Stack here: |
2462 // - home_object | 2409 // - home_object |
2463 // - this (receiver) | 2410 // - this (receiver) |
2464 // - this (receiver) <-- LoadFromSuper will pop here and below. | 2411 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2465 // - home_object | 2412 // - home_object |
2466 __ CallRuntime(Runtime::kLoadFromSuper); | 2413 // - key |
| 2414 CallRuntimeWithOperands(Runtime::kLoadFromSuper); |
2467 | 2415 |
2468 // Replace home_object with target function. | 2416 // Replace home_object with target function. |
2469 __ Poke(x0, kPointerSize); | 2417 __ Poke(x0, kPointerSize); |
2470 | 2418 |
2471 // Stack here: | 2419 // Stack here: |
2472 // - target function | 2420 // - target function |
2473 // - this (receiver) | 2421 // - this (receiver) |
2474 EmitCall(expr); | 2422 EmitCall(expr); |
2475 } | 2423 } |
2476 | 2424 |
2477 | 2425 |
2478 // Code common for calls using the IC. | 2426 // Code common for calls using the IC. |
2479 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2427 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2480 Expression* key) { | 2428 Expression* key) { |
2481 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); | 2429 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); |
2482 // Load the key. | 2430 // Load the key. |
2483 VisitForAccumulatorValue(key); | 2431 VisitForAccumulatorValue(key); |
2484 | 2432 |
2485 Expression* callee = expr->expression(); | 2433 Expression* callee = expr->expression(); |
2486 | 2434 |
2487 // Load the function from the receiver. | 2435 // Load the function from the receiver. |
2488 DCHECK(callee->IsProperty()); | 2436 DCHECK(callee->IsProperty()); |
2489 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2437 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
2490 __ Move(LoadDescriptor::NameRegister(), x0); | 2438 __ Move(LoadDescriptor::NameRegister(), x0); |
2491 EmitKeyedPropertyLoad(callee->AsProperty()); | 2439 EmitKeyedPropertyLoad(callee->AsProperty()); |
2492 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2440 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2493 | 2441 |
2494 // Push the target function under the receiver. | 2442 // Push the target function under the receiver. |
2495 __ Pop(x10); | 2443 PopOperand(x10); |
2496 __ Push(x0, x10); | 2444 PushOperands(x0, x10); |
2497 | 2445 |
2498 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 2446 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
2499 } | 2447 } |
2500 | 2448 |
2501 | 2449 |
2502 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2450 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2503 ASM_LOCATION("FullCodeGenerator::EmitKeyedSuperCallWithLoadIC"); | 2451 ASM_LOCATION("FullCodeGenerator::EmitKeyedSuperCallWithLoadIC"); |
2504 Expression* callee = expr->expression(); | 2452 Expression* callee = expr->expression(); |
2505 DCHECK(callee->IsProperty()); | 2453 DCHECK(callee->IsProperty()); |
2506 Property* prop = callee->AsProperty(); | 2454 Property* prop = callee->AsProperty(); |
2507 DCHECK(prop->IsSuperAccess()); | 2455 DCHECK(prop->IsSuperAccess()); |
2508 SetExpressionPosition(prop); | 2456 SetExpressionPosition(prop); |
2509 | 2457 |
2510 // Load the function from the receiver. | 2458 // Load the function from the receiver. |
2511 const Register scratch = x10; | 2459 const Register scratch = x10; |
2512 SuperPropertyReference* super_ref = | 2460 SuperPropertyReference* super_ref = |
2513 callee->AsProperty()->obj()->AsSuperPropertyReference(); | 2461 callee->AsProperty()->obj()->AsSuperPropertyReference(); |
2514 VisitForStackValue(super_ref->home_object()); | 2462 VisitForStackValue(super_ref->home_object()); |
2515 VisitForAccumulatorValue(super_ref->this_var()); | 2463 VisitForAccumulatorValue(super_ref->this_var()); |
2516 __ Push(x0); | 2464 PushOperand(x0); |
2517 __ Peek(scratch, kPointerSize); | 2465 __ Peek(scratch, kPointerSize); |
2518 __ Push(x0, scratch); | 2466 PushOperands(x0, scratch); |
2519 VisitForStackValue(prop->key()); | 2467 VisitForStackValue(prop->key()); |
2520 | 2468 |
2521 // Stack here: | 2469 // Stack here: |
2522 // - home_object | 2470 // - home_object |
2523 // - this (receiver) | 2471 // - this (receiver) |
2524 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | 2472 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. |
2525 // - home_object | 2473 // - home_object |
2526 // - key | 2474 // - key |
2527 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | 2475 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); |
2528 | 2476 |
2529 // Replace home_object with target function. | 2477 // Replace home_object with target function. |
2530 __ Poke(x0, kPointerSize); | 2478 __ Poke(x0, kPointerSize); |
2531 | 2479 |
2532 // Stack here: | 2480 // Stack here: |
2533 // - target function | 2481 // - target function |
2534 // - this (receiver) | 2482 // - this (receiver) |
2535 EmitCall(expr); | 2483 EmitCall(expr); |
2536 } | 2484 } |
2537 | 2485 |
(...skipping 18 matching lines...) Expand all Loading... |
2556 EmitProfilingCounterHandlingForReturnSequence(true); | 2504 EmitProfilingCounterHandlingForReturnSequence(true); |
2557 } | 2505 } |
2558 Handle<Code> ic = | 2506 Handle<Code> ic = |
2559 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2507 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2560 .code(); | 2508 .code(); |
2561 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); | 2509 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); |
2562 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2510 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2563 // Don't assign a type feedback id to the IC, since type feedback is provided | 2511 // Don't assign a type feedback id to the IC, since type feedback is provided |
2564 // by the vector above. | 2512 // by the vector above. |
2565 CallIC(ic); | 2513 CallIC(ic); |
| 2514 OperandStackDepthDecrement(arg_count + 1); |
2566 | 2515 |
2567 RecordJSReturnSite(expr); | 2516 RecordJSReturnSite(expr); |
2568 // Restore context register. | 2517 // Restore context register. |
2569 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2518 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2570 context()->DropAndPlug(1, x0); | 2519 context()->DropAndPlug(1, x0); |
2571 } | 2520 } |
2572 | 2521 |
2573 | 2522 |
2574 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2523 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
2575 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); | 2524 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); |
(...skipping 28 matching lines...) Expand all Loading... |
2604 SetExpressionPosition(callee); | 2553 SetExpressionPosition(callee); |
2605 // Generate code for loading from variables potentially shadowed | 2554 // Generate code for loading from variables potentially shadowed |
2606 // by eval-introduced variables. | 2555 // by eval-introduced variables. |
2607 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 2556 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
2608 | 2557 |
2609 __ Bind(&slow); | 2558 __ Bind(&slow); |
2610 // Call the runtime to find the function to call (returned in x0) | 2559 // Call the runtime to find the function to call (returned in x0) |
2611 // and the object holding it (returned in x1). | 2560 // and the object holding it (returned in x1). |
2612 __ Push(callee->name()); | 2561 __ Push(callee->name()); |
2613 __ CallRuntime(Runtime::kLoadLookupSlotForCall); | 2562 __ CallRuntime(Runtime::kLoadLookupSlotForCall); |
2614 __ Push(x0, x1); // Receiver, function. | 2563 PushOperands(x0, x1); // Receiver, function. |
2615 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 2564 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
2616 | 2565 |
2617 // If fast case code has been generated, emit code to push the | 2566 // If fast case code has been generated, emit code to push the |
2618 // function and receiver and have the slow path jump around this | 2567 // function and receiver and have the slow path jump around this |
2619 // code. | 2568 // code. |
2620 if (done.is_linked()) { | 2569 if (done.is_linked()) { |
2621 Label call; | 2570 Label call; |
2622 __ B(&call); | 2571 __ B(&call); |
2623 __ Bind(&done); | 2572 __ Bind(&done); |
2624 // Push function. | 2573 // Push function. |
2625 // The receiver is implicitly the global receiver. Indicate this | 2574 // The receiver is implicitly the global receiver. Indicate this |
2626 // by passing the undefined to the call function stub. | 2575 // by passing the undefined to the call function stub. |
2627 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); | 2576 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
2628 __ Push(x0, x1); | 2577 __ Push(x0, x1); |
2629 __ Bind(&call); | 2578 __ Bind(&call); |
2630 } | 2579 } |
2631 } else { | 2580 } else { |
2632 VisitForStackValue(callee); | 2581 VisitForStackValue(callee); |
2633 // refEnv.WithBaseObject() | 2582 // refEnv.WithBaseObject() |
2634 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); | 2583 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); |
2635 __ Push(x10); // Reserved receiver slot. | 2584 PushOperand(x10); // Reserved receiver slot. |
2636 } | 2585 } |
2637 } | 2586 } |
2638 | 2587 |
2639 | 2588 |
2640 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { | 2589 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { |
2641 ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall"); | 2590 ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall"); |
2642 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 2591 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
2643 // to resolve the function we need to call. Then we call the resolved | 2592 // to resolve the function we need to call. Then we call the resolved |
2644 // function using the given arguments. | 2593 // function using the given arguments. |
2645 ZoneList<Expression*>* args = expr->arguments(); | 2594 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 19 matching lines...) Expand all Loading... |
2665 | 2614 |
2666 // Record source position for debugger. | 2615 // Record source position for debugger. |
2667 SetCallPosition(expr); | 2616 SetCallPosition(expr); |
2668 | 2617 |
2669 // Call the evaluated function. | 2618 // Call the evaluated function. |
2670 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2619 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2671 __ Mov(x0, arg_count); | 2620 __ Mov(x0, arg_count); |
2672 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2621 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2673 expr->tail_call_mode()), | 2622 expr->tail_call_mode()), |
2674 RelocInfo::CODE_TARGET); | 2623 RelocInfo::CODE_TARGET); |
| 2624 OperandStackDepthDecrement(arg_count + 1); |
2675 RecordJSReturnSite(expr); | 2625 RecordJSReturnSite(expr); |
2676 // Restore context register. | 2626 // Restore context register. |
2677 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2627 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2678 context()->DropAndPlug(1, x0); | 2628 context()->DropAndPlug(1, x0); |
2679 } | 2629 } |
2680 | 2630 |
2681 | 2631 |
2682 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2632 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2683 Comment cmnt(masm_, "[ CallNew"); | 2633 Comment cmnt(masm_, "[ CallNew"); |
2684 // According to ECMA-262, section 11.2.2, page 44, the function | 2634 // According to ECMA-262, section 11.2.2, page 44, the function |
(...skipping 20 matching lines...) Expand all Loading... |
2705 // Load function and argument count into x1 and x0. | 2655 // Load function and argument count into x1 and x0. |
2706 __ Mov(x0, arg_count); | 2656 __ Mov(x0, arg_count); |
2707 __ Peek(x1, arg_count * kXRegSize); | 2657 __ Peek(x1, arg_count * kXRegSize); |
2708 | 2658 |
2709 // Record call targets in unoptimized code. | 2659 // Record call targets in unoptimized code. |
2710 __ EmitLoadTypeFeedbackVector(x2); | 2660 __ EmitLoadTypeFeedbackVector(x2); |
2711 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); | 2661 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); |
2712 | 2662 |
2713 CallConstructStub stub(isolate()); | 2663 CallConstructStub stub(isolate()); |
2714 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2664 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 2665 OperandStackDepthDecrement(arg_count + 1); |
2715 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2666 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2716 // Restore context register. | 2667 // Restore context register. |
2717 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2668 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2718 context()->Plug(x0); | 2669 context()->Plug(x0); |
2719 } | 2670 } |
2720 | 2671 |
2721 | 2672 |
2722 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2673 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
2723 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); | 2674 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); |
2724 SuperCallReference* super_call_ref = | 2675 SuperCallReference* super_call_ref = |
2725 expr->expression()->AsSuperCallReference(); | 2676 expr->expression()->AsSuperCallReference(); |
2726 DCHECK_NOT_NULL(super_call_ref); | 2677 DCHECK_NOT_NULL(super_call_ref); |
2727 | 2678 |
2728 // Push the super constructor target on the stack (may be null, | 2679 // Push the super constructor target on the stack (may be null, |
2729 // but the Construct builtin can deal with that properly). | 2680 // but the Construct builtin can deal with that properly). |
2730 VisitForAccumulatorValue(super_call_ref->this_function_var()); | 2681 VisitForAccumulatorValue(super_call_ref->this_function_var()); |
2731 __ AssertFunction(result_register()); | 2682 __ AssertFunction(result_register()); |
2732 __ Ldr(result_register(), | 2683 __ Ldr(result_register(), |
2733 FieldMemOperand(result_register(), HeapObject::kMapOffset)); | 2684 FieldMemOperand(result_register(), HeapObject::kMapOffset)); |
2734 __ Ldr(result_register(), | 2685 __ Ldr(result_register(), |
2735 FieldMemOperand(result_register(), Map::kPrototypeOffset)); | 2686 FieldMemOperand(result_register(), Map::kPrototypeOffset)); |
2736 __ Push(result_register()); | 2687 PushOperand(result_register()); |
2737 | 2688 |
2738 // Push the arguments ("left-to-right") on the stack. | 2689 // Push the arguments ("left-to-right") on the stack. |
2739 ZoneList<Expression*>* args = expr->arguments(); | 2690 ZoneList<Expression*>* args = expr->arguments(); |
2740 int arg_count = args->length(); | 2691 int arg_count = args->length(); |
2741 for (int i = 0; i < arg_count; i++) { | 2692 for (int i = 0; i < arg_count; i++) { |
2742 VisitForStackValue(args->at(i)); | 2693 VisitForStackValue(args->at(i)); |
2743 } | 2694 } |
2744 | 2695 |
2745 // Call the construct call builtin that handles allocation and | 2696 // Call the construct call builtin that handles allocation and |
2746 // constructor invocation. | 2697 // constructor invocation. |
2747 SetConstructCallPosition(expr); | 2698 SetConstructCallPosition(expr); |
2748 | 2699 |
2749 // Load new target into x3. | 2700 // Load new target into x3. |
2750 VisitForAccumulatorValue(super_call_ref->new_target_var()); | 2701 VisitForAccumulatorValue(super_call_ref->new_target_var()); |
2751 __ Mov(x3, result_register()); | 2702 __ Mov(x3, result_register()); |
2752 | 2703 |
2753 // Load function and argument count into x1 and x0. | 2704 // Load function and argument count into x1 and x0. |
2754 __ Mov(x0, arg_count); | 2705 __ Mov(x0, arg_count); |
2755 __ Peek(x1, arg_count * kXRegSize); | 2706 __ Peek(x1, arg_count * kXRegSize); |
2756 | 2707 |
2757 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2708 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 2709 OperandStackDepthDecrement(arg_count + 1); |
2758 | 2710 |
2759 RecordJSReturnSite(expr); | 2711 RecordJSReturnSite(expr); |
2760 | 2712 |
2761 // Restore context register. | 2713 // Restore context register. |
2762 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2714 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2763 context()->Plug(x0); | 2715 context()->Plug(x0); |
2764 } | 2716 } |
2765 | 2717 |
2766 | 2718 |
2767 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2719 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2971 DCHECK_EQ(3, args->length()); | 2923 DCHECK_EQ(3, args->length()); |
2972 | 2924 |
2973 Register string = x0; | 2925 Register string = x0; |
2974 Register index = x1; | 2926 Register index = x1; |
2975 Register value = x2; | 2927 Register value = x2; |
2976 Register scratch = x10; | 2928 Register scratch = x10; |
2977 | 2929 |
2978 VisitForStackValue(args->at(0)); // index | 2930 VisitForStackValue(args->at(0)); // index |
2979 VisitForStackValue(args->at(1)); // value | 2931 VisitForStackValue(args->at(1)); // value |
2980 VisitForAccumulatorValue(args->at(2)); // string | 2932 VisitForAccumulatorValue(args->at(2)); // string |
2981 __ Pop(value, index); | 2933 PopOperands(value, index); |
2982 | 2934 |
2983 if (FLAG_debug_code) { | 2935 if (FLAG_debug_code) { |
2984 __ AssertSmi(value, kNonSmiValue); | 2936 __ AssertSmi(value, kNonSmiValue); |
2985 __ AssertSmi(index, kNonSmiIndex); | 2937 __ AssertSmi(index, kNonSmiIndex); |
2986 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 2938 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
2987 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, | 2939 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, |
2988 one_byte_seq_type); | 2940 one_byte_seq_type); |
2989 } | 2941 } |
2990 | 2942 |
2991 __ Add(scratch, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); | 2943 __ Add(scratch, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); |
2992 __ SmiUntag(value); | 2944 __ SmiUntag(value); |
2993 __ SmiUntag(index); | 2945 __ SmiUntag(index); |
2994 __ Strb(value, MemOperand(scratch, index)); | 2946 __ Strb(value, MemOperand(scratch, index)); |
2995 context()->Plug(string); | 2947 context()->Plug(string); |
2996 } | 2948 } |
2997 | 2949 |
2998 | 2950 |
2999 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { | 2951 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { |
3000 ZoneList<Expression*>* args = expr->arguments(); | 2952 ZoneList<Expression*>* args = expr->arguments(); |
3001 DCHECK_EQ(3, args->length()); | 2953 DCHECK_EQ(3, args->length()); |
3002 | 2954 |
3003 Register string = x0; | 2955 Register string = x0; |
3004 Register index = x1; | 2956 Register index = x1; |
3005 Register value = x2; | 2957 Register value = x2; |
3006 Register scratch = x10; | 2958 Register scratch = x10; |
3007 | 2959 |
3008 VisitForStackValue(args->at(0)); // index | 2960 VisitForStackValue(args->at(0)); // index |
3009 VisitForStackValue(args->at(1)); // value | 2961 VisitForStackValue(args->at(1)); // value |
3010 VisitForAccumulatorValue(args->at(2)); // string | 2962 VisitForAccumulatorValue(args->at(2)); // string |
3011 __ Pop(value, index); | 2963 PopOperands(value, index); |
3012 | 2964 |
3013 if (FLAG_debug_code) { | 2965 if (FLAG_debug_code) { |
3014 __ AssertSmi(value, kNonSmiValue); | 2966 __ AssertSmi(value, kNonSmiValue); |
3015 __ AssertSmi(index, kNonSmiIndex); | 2967 __ AssertSmi(index, kNonSmiIndex); |
3016 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 2968 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
3017 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, | 2969 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, |
3018 two_byte_seq_type); | 2970 two_byte_seq_type); |
3019 } | 2971 } |
3020 | 2972 |
3021 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); | 2973 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3069 ZoneList<Expression*>* args = expr->arguments(); | 3021 ZoneList<Expression*>* args = expr->arguments(); |
3070 DCHECK(args->length() == 2); | 3022 DCHECK(args->length() == 2); |
3071 | 3023 |
3072 VisitForStackValue(args->at(0)); | 3024 VisitForStackValue(args->at(0)); |
3073 VisitForAccumulatorValue(args->at(1)); | 3025 VisitForAccumulatorValue(args->at(1)); |
3074 | 3026 |
3075 Register object = x1; | 3027 Register object = x1; |
3076 Register index = x0; | 3028 Register index = x0; |
3077 Register result = x3; | 3029 Register result = x3; |
3078 | 3030 |
3079 __ Pop(object); | 3031 PopOperand(object); |
3080 | 3032 |
3081 Label need_conversion; | 3033 Label need_conversion; |
3082 Label index_out_of_range; | 3034 Label index_out_of_range; |
3083 Label done; | 3035 Label done; |
3084 StringCharCodeAtGenerator generator(object, | 3036 StringCharCodeAtGenerator generator(object, |
3085 index, | 3037 index, |
3086 result, | 3038 result, |
3087 &need_conversion, | 3039 &need_conversion, |
3088 &need_conversion, | 3040 &need_conversion, |
3089 &index_out_of_range, | 3041 &index_out_of_range, |
(...skipping 24 matching lines...) Expand all Loading... |
3114 ZoneList<Expression*>* args = expr->arguments(); | 3066 ZoneList<Expression*>* args = expr->arguments(); |
3115 DCHECK(args->length() == 2); | 3067 DCHECK(args->length() == 2); |
3116 | 3068 |
3117 VisitForStackValue(args->at(0)); | 3069 VisitForStackValue(args->at(0)); |
3118 VisitForAccumulatorValue(args->at(1)); | 3070 VisitForAccumulatorValue(args->at(1)); |
3119 | 3071 |
3120 Register object = x1; | 3072 Register object = x1; |
3121 Register index = x0; | 3073 Register index = x0; |
3122 Register result = x0; | 3074 Register result = x0; |
3123 | 3075 |
3124 __ Pop(object); | 3076 PopOperand(object); |
3125 | 3077 |
3126 Label need_conversion; | 3078 Label need_conversion; |
3127 Label index_out_of_range; | 3079 Label index_out_of_range; |
3128 Label done; | 3080 Label done; |
3129 StringCharAtGenerator generator(object, | 3081 StringCharAtGenerator generator(object, |
3130 index, | 3082 index, |
3131 x3, | 3083 x3, |
3132 result, | 3084 result, |
3133 &need_conversion, | 3085 &need_conversion, |
3134 &need_conversion, | 3086 &need_conversion, |
(...skipping 29 matching lines...) Expand all Loading... |
3164 for (Expression* const arg : *args) { | 3116 for (Expression* const arg : *args) { |
3165 VisitForStackValue(arg); | 3117 VisitForStackValue(arg); |
3166 } | 3118 } |
3167 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3119 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3168 // Move target to x1. | 3120 // Move target to x1. |
3169 int const argc = args->length() - 2; | 3121 int const argc = args->length() - 2; |
3170 __ Peek(x1, (argc + 1) * kXRegSize); | 3122 __ Peek(x1, (argc + 1) * kXRegSize); |
3171 // Call the target. | 3123 // Call the target. |
3172 __ Mov(x0, argc); | 3124 __ Mov(x0, argc); |
3173 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3125 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 3126 OperandStackDepthDecrement(argc + 1); |
3174 // Restore context register. | 3127 // Restore context register. |
3175 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3128 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3176 // Discard the function left on TOS. | 3129 // Discard the function left on TOS. |
3177 context()->DropAndPlug(1, x0); | 3130 context()->DropAndPlug(1, x0); |
3178 } | 3131 } |
3179 | 3132 |
3180 | 3133 |
3181 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3134 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3182 ZoneList<Expression*>* args = expr->arguments(); | 3135 ZoneList<Expression*>* args = expr->arguments(); |
3183 VisitForAccumulatorValue(args->at(0)); | 3136 VisitForAccumulatorValue(args->at(0)); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3260 __ ObjectUntag(untagged_result, result); | 3213 __ ObjectUntag(untagged_result, result); |
3261 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); | 3214 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); |
3262 __ Stp(empty_fixed_array, empty_fixed_array, | 3215 __ Stp(empty_fixed_array, empty_fixed_array, |
3263 MemOperand(untagged_result, JSObject::kPropertiesOffset)); | 3216 MemOperand(untagged_result, JSObject::kPropertiesOffset)); |
3264 __ Stp(result_value, boolean_done, | 3217 __ Stp(result_value, boolean_done, |
3265 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); | 3218 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); |
3266 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 3219 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
3267 __ B(&done); | 3220 __ B(&done); |
3268 | 3221 |
3269 __ Bind(&runtime); | 3222 __ Bind(&runtime); |
3270 __ CallRuntime(Runtime::kCreateIterResultObject); | 3223 CallRuntimeWithOperands(Runtime::kCreateIterResultObject); |
3271 | 3224 |
3272 __ Bind(&done); | 3225 __ Bind(&done); |
3273 context()->Plug(x0); | 3226 context()->Plug(x0); |
3274 } | 3227 } |
3275 | 3228 |
3276 | 3229 |
3277 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 3230 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
3278 // Push undefined as the receiver. | 3231 // Push undefined as the receiver. |
3279 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | 3232 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |
3280 __ Push(x0); | 3233 PushOperand(x0); |
3281 | 3234 |
3282 __ LoadNativeContextSlot(expr->context_index(), x0); | 3235 __ LoadNativeContextSlot(expr->context_index(), x0); |
3283 } | 3236 } |
3284 | 3237 |
3285 | 3238 |
3286 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3239 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3287 ZoneList<Expression*>* args = expr->arguments(); | 3240 ZoneList<Expression*>* args = expr->arguments(); |
3288 int arg_count = args->length(); | 3241 int arg_count = args->length(); |
3289 | 3242 |
3290 SetCallPosition(expr); | 3243 SetCallPosition(expr); |
3291 __ Peek(x1, (arg_count + 1) * kPointerSize); | 3244 __ Peek(x1, (arg_count + 1) * kPointerSize); |
3292 __ Mov(x0, arg_count); | 3245 __ Mov(x0, arg_count); |
3293 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3246 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
3294 RelocInfo::CODE_TARGET); | 3247 RelocInfo::CODE_TARGET); |
| 3248 OperandStackDepthDecrement(arg_count + 1); |
3295 } | 3249 } |
3296 | 3250 |
3297 | 3251 |
3298 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 3252 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
3299 ZoneList<Expression*>* args = expr->arguments(); | 3253 ZoneList<Expression*>* args = expr->arguments(); |
3300 int arg_count = args->length(); | 3254 int arg_count = args->length(); |
3301 | 3255 |
3302 if (expr->is_jsruntime()) { | 3256 if (expr->is_jsruntime()) { |
3303 Comment cmnt(masm_, "[ CallRunTime"); | 3257 Comment cmnt(masm_, "[ CallRunTime"); |
3304 EmitLoadJSRuntimeFunction(expr); | 3258 EmitLoadJSRuntimeFunction(expr); |
3305 | 3259 |
3306 // Push the target function under the receiver. | 3260 // Push the target function under the receiver. |
3307 __ Pop(x10); | 3261 PopOperand(x10); |
3308 __ Push(x0, x10); | 3262 PushOperands(x0, x10); |
3309 | 3263 |
3310 for (int i = 0; i < arg_count; i++) { | 3264 for (int i = 0; i < arg_count; i++) { |
3311 VisitForStackValue(args->at(i)); | 3265 VisitForStackValue(args->at(i)); |
3312 } | 3266 } |
3313 | 3267 |
3314 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3268 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3315 EmitCallJSRuntimeFunction(expr); | 3269 EmitCallJSRuntimeFunction(expr); |
3316 | 3270 |
3317 // Restore context register. | 3271 // Restore context register. |
3318 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3272 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
(...skipping 13 matching lines...) Expand all Loading... |
3332 default: { | 3286 default: { |
3333 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); | 3287 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); |
3334 // Push the arguments ("left-to-right"). | 3288 // Push the arguments ("left-to-right"). |
3335 for (int i = 0; i < arg_count; i++) { | 3289 for (int i = 0; i < arg_count; i++) { |
3336 VisitForStackValue(args->at(i)); | 3290 VisitForStackValue(args->at(i)); |
3337 } | 3291 } |
3338 | 3292 |
3339 // Call the C runtime function. | 3293 // Call the C runtime function. |
3340 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3294 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3341 __ CallRuntime(expr->function(), arg_count); | 3295 __ CallRuntime(expr->function(), arg_count); |
| 3296 OperandStackDepthDecrement(arg_count); |
3342 context()->Plug(x0); | 3297 context()->Plug(x0); |
3343 } | 3298 } |
3344 } | 3299 } |
3345 } | 3300 } |
3346 } | 3301 } |
3347 | 3302 |
3348 | 3303 |
3349 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3304 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3350 switch (expr->op()) { | 3305 switch (expr->op()) { |
3351 case Token::DELETE: { | 3306 case Token::DELETE: { |
3352 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3307 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3353 Property* property = expr->expression()->AsProperty(); | 3308 Property* property = expr->expression()->AsProperty(); |
3354 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3309 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3355 | 3310 |
3356 if (property != NULL) { | 3311 if (property != NULL) { |
3357 VisitForStackValue(property->obj()); | 3312 VisitForStackValue(property->obj()); |
3358 VisitForStackValue(property->key()); | 3313 VisitForStackValue(property->key()); |
3359 __ CallRuntime(is_strict(language_mode()) | 3314 CallRuntimeWithOperands(is_strict(language_mode()) |
3360 ? Runtime::kDeleteProperty_Strict | 3315 ? Runtime::kDeleteProperty_Strict |
3361 : Runtime::kDeleteProperty_Sloppy); | 3316 : Runtime::kDeleteProperty_Sloppy); |
3362 context()->Plug(x0); | 3317 context()->Plug(x0); |
3363 } else if (proxy != NULL) { | 3318 } else if (proxy != NULL) { |
3364 Variable* var = proxy->var(); | 3319 Variable* var = proxy->var(); |
3365 // Delete of an unqualified identifier is disallowed in strict mode but | 3320 // Delete of an unqualified identifier is disallowed in strict mode but |
3366 // "delete this" is allowed. | 3321 // "delete this" is allowed. |
3367 bool is_this = var->HasThisName(isolate()); | 3322 bool is_this = var->HasThisName(isolate()); |
3368 DCHECK(is_sloppy(language_mode()) || is_this); | 3323 DCHECK(is_sloppy(language_mode()) || is_this); |
3369 if (var->IsUnallocatedOrGlobalSlot()) { | 3324 if (var->IsUnallocatedOrGlobalSlot()) { |
3370 __ LoadGlobalObject(x12); | 3325 __ LoadGlobalObject(x12); |
3371 __ Mov(x11, Operand(var->name())); | 3326 __ Mov(x11, Operand(var->name())); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3414 context()->Plug(test->true_label(), test->false_label()); | 3369 context()->Plug(test->true_label(), test->false_label()); |
3415 } else { | 3370 } else { |
3416 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); | 3371 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); |
3417 // TODO(jbramley): This could be much more efficient using (for | 3372 // TODO(jbramley): This could be much more efficient using (for |
3418 // example) the CSEL instruction. | 3373 // example) the CSEL instruction. |
3419 Label materialize_true, materialize_false, done; | 3374 Label materialize_true, materialize_false, done; |
3420 VisitForControl(expr->expression(), | 3375 VisitForControl(expr->expression(), |
3421 &materialize_false, | 3376 &materialize_false, |
3422 &materialize_true, | 3377 &materialize_true, |
3423 &materialize_true); | 3378 &materialize_true); |
| 3379 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); |
3424 | 3380 |
3425 __ Bind(&materialize_true); | 3381 __ Bind(&materialize_true); |
3426 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); | 3382 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); |
3427 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); | 3383 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); |
3428 __ B(&done); | 3384 __ B(&done); |
3429 | 3385 |
3430 __ Bind(&materialize_false); | 3386 __ Bind(&materialize_false); |
3431 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); | 3387 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); |
3432 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); | 3388 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); |
3433 __ B(&done); | 3389 __ B(&done); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3466 LhsKind assign_type = Property::GetAssignType(prop); | 3422 LhsKind assign_type = Property::GetAssignType(prop); |
3467 | 3423 |
3468 // Evaluate expression and get value. | 3424 // Evaluate expression and get value. |
3469 if (assign_type == VARIABLE) { | 3425 if (assign_type == VARIABLE) { |
3470 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 3426 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
3471 AccumulatorValueContext context(this); | 3427 AccumulatorValueContext context(this); |
3472 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 3428 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
3473 } else { | 3429 } else { |
3474 // Reserve space for result of postfix operation. | 3430 // Reserve space for result of postfix operation. |
3475 if (expr->is_postfix() && !context()->IsEffect()) { | 3431 if (expr->is_postfix() && !context()->IsEffect()) { |
3476 __ Push(xzr); | 3432 PushOperand(xzr); |
3477 } | 3433 } |
3478 switch (assign_type) { | 3434 switch (assign_type) { |
3479 case NAMED_PROPERTY: { | 3435 case NAMED_PROPERTY: { |
3480 // Put the object both on the stack and in the register. | 3436 // Put the object both on the stack and in the register. |
3481 VisitForStackValue(prop->obj()); | 3437 VisitForStackValue(prop->obj()); |
3482 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 3438 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
3483 EmitNamedPropertyLoad(prop); | 3439 EmitNamedPropertyLoad(prop); |
3484 break; | 3440 break; |
3485 } | 3441 } |
3486 | 3442 |
3487 case NAMED_SUPER_PROPERTY: { | 3443 case NAMED_SUPER_PROPERTY: { |
3488 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3444 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
3489 VisitForAccumulatorValue( | 3445 VisitForAccumulatorValue( |
3490 prop->obj()->AsSuperPropertyReference()->home_object()); | 3446 prop->obj()->AsSuperPropertyReference()->home_object()); |
3491 __ Push(result_register()); | 3447 PushOperand(result_register()); |
3492 const Register scratch = x10; | 3448 const Register scratch = x10; |
3493 __ Peek(scratch, kPointerSize); | 3449 __ Peek(scratch, kPointerSize); |
3494 __ Push(scratch, result_register()); | 3450 PushOperands(scratch, result_register()); |
3495 EmitNamedSuperPropertyLoad(prop); | 3451 EmitNamedSuperPropertyLoad(prop); |
3496 break; | 3452 break; |
3497 } | 3453 } |
3498 | 3454 |
3499 case KEYED_SUPER_PROPERTY: { | 3455 case KEYED_SUPER_PROPERTY: { |
3500 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3456 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
3501 VisitForStackValue( | 3457 VisitForStackValue( |
3502 prop->obj()->AsSuperPropertyReference()->home_object()); | 3458 prop->obj()->AsSuperPropertyReference()->home_object()); |
3503 VisitForAccumulatorValue(prop->key()); | 3459 VisitForAccumulatorValue(prop->key()); |
3504 __ Push(result_register()); | 3460 PushOperand(result_register()); |
3505 const Register scratch1 = x10; | 3461 const Register scratch1 = x10; |
3506 const Register scratch2 = x11; | 3462 const Register scratch2 = x11; |
3507 __ Peek(scratch1, 2 * kPointerSize); | 3463 __ Peek(scratch1, 2 * kPointerSize); |
3508 __ Peek(scratch2, kPointerSize); | 3464 __ Peek(scratch2, kPointerSize); |
3509 __ Push(scratch1, scratch2, result_register()); | 3465 PushOperands(scratch1, scratch2, result_register()); |
3510 EmitKeyedSuperPropertyLoad(prop); | 3466 EmitKeyedSuperPropertyLoad(prop); |
3511 break; | 3467 break; |
3512 } | 3468 } |
3513 | 3469 |
3514 case KEYED_PROPERTY: { | 3470 case KEYED_PROPERTY: { |
3515 VisitForStackValue(prop->obj()); | 3471 VisitForStackValue(prop->obj()); |
3516 VisitForStackValue(prop->key()); | 3472 VisitForStackValue(prop->key()); |
3517 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); | 3473 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
3518 __ Peek(LoadDescriptor::NameRegister(), 0); | 3474 __ Peek(LoadDescriptor::NameRegister(), 0); |
3519 EmitKeyedPropertyLoad(prop); | 3475 EmitKeyedPropertyLoad(prop); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3582 } | 3538 } |
3583 | 3539 |
3584 // Save result for postfix expressions. | 3540 // Save result for postfix expressions. |
3585 if (expr->is_postfix()) { | 3541 if (expr->is_postfix()) { |
3586 if (!context()->IsEffect()) { | 3542 if (!context()->IsEffect()) { |
3587 // Save the result on the stack. If we have a named or keyed property | 3543 // Save the result on the stack. If we have a named or keyed property |
3588 // we store the result under the receiver that is currently on top | 3544 // we store the result under the receiver that is currently on top |
3589 // of the stack. | 3545 // of the stack. |
3590 switch (assign_type) { | 3546 switch (assign_type) { |
3591 case VARIABLE: | 3547 case VARIABLE: |
3592 __ Push(x0); | 3548 PushOperand(x0); |
3593 break; | 3549 break; |
3594 case NAMED_PROPERTY: | 3550 case NAMED_PROPERTY: |
3595 __ Poke(x0, kXRegSize); | 3551 __ Poke(x0, kXRegSize); |
3596 break; | 3552 break; |
3597 case NAMED_SUPER_PROPERTY: | 3553 case NAMED_SUPER_PROPERTY: |
3598 __ Poke(x0, 2 * kXRegSize); | 3554 __ Poke(x0, 2 * kXRegSize); |
3599 break; | 3555 break; |
3600 case KEYED_PROPERTY: | 3556 case KEYED_PROPERTY: |
3601 __ Poke(x0, 2 * kXRegSize); | 3557 __ Poke(x0, 2 * kXRegSize); |
3602 break; | 3558 break; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3642 } else { | 3598 } else { |
3643 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3599 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3644 Token::ASSIGN, expr->CountSlot()); | 3600 Token::ASSIGN, expr->CountSlot()); |
3645 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3601 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3646 context()->Plug(x0); | 3602 context()->Plug(x0); |
3647 } | 3603 } |
3648 break; | 3604 break; |
3649 case NAMED_PROPERTY: { | 3605 case NAMED_PROPERTY: { |
3650 __ Mov(StoreDescriptor::NameRegister(), | 3606 __ Mov(StoreDescriptor::NameRegister(), |
3651 Operand(prop->key()->AsLiteral()->value())); | 3607 Operand(prop->key()->AsLiteral()->value())); |
3652 __ Pop(StoreDescriptor::ReceiverRegister()); | 3608 PopOperand(StoreDescriptor::ReceiverRegister()); |
3653 EmitLoadStoreICSlot(expr->CountSlot()); | 3609 EmitLoadStoreICSlot(expr->CountSlot()); |
3654 CallStoreIC(); | 3610 CallStoreIC(); |
3655 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3611 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3656 if (expr->is_postfix()) { | 3612 if (expr->is_postfix()) { |
3657 if (!context()->IsEffect()) { | 3613 if (!context()->IsEffect()) { |
3658 context()->PlugTOS(); | 3614 context()->PlugTOS(); |
3659 } | 3615 } |
3660 } else { | 3616 } else { |
3661 context()->Plug(x0); | 3617 context()->Plug(x0); |
3662 } | 3618 } |
(...skipping 15 matching lines...) Expand all Loading... |
3678 if (expr->is_postfix()) { | 3634 if (expr->is_postfix()) { |
3679 if (!context()->IsEffect()) { | 3635 if (!context()->IsEffect()) { |
3680 context()->PlugTOS(); | 3636 context()->PlugTOS(); |
3681 } | 3637 } |
3682 } else { | 3638 } else { |
3683 context()->Plug(x0); | 3639 context()->Plug(x0); |
3684 } | 3640 } |
3685 break; | 3641 break; |
3686 } | 3642 } |
3687 case KEYED_PROPERTY: { | 3643 case KEYED_PROPERTY: { |
3688 __ Pop(StoreDescriptor::NameRegister()); | 3644 PopOperand(StoreDescriptor::NameRegister()); |
3689 __ Pop(StoreDescriptor::ReceiverRegister()); | 3645 PopOperand(StoreDescriptor::ReceiverRegister()); |
3690 Handle<Code> ic = | 3646 Handle<Code> ic = |
3691 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 3647 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
3692 EmitLoadStoreICSlot(expr->CountSlot()); | 3648 EmitLoadStoreICSlot(expr->CountSlot()); |
3693 CallIC(ic); | 3649 CallIC(ic); |
3694 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3650 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3695 if (expr->is_postfix()) { | 3651 if (expr->is_postfix()) { |
3696 if (!context()->IsEffect()) { | 3652 if (!context()->IsEffect()) { |
3697 context()->PlugTOS(); | 3653 context()->PlugTOS(); |
3698 } | 3654 } |
3699 } else { | 3655 } else { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3810 Label* if_false = NULL; | 3766 Label* if_false = NULL; |
3811 Label* fall_through = NULL; | 3767 Label* fall_through = NULL; |
3812 context()->PrepareTest(&materialize_true, &materialize_false, | 3768 context()->PrepareTest(&materialize_true, &materialize_false, |
3813 &if_true, &if_false, &fall_through); | 3769 &if_true, &if_false, &fall_through); |
3814 | 3770 |
3815 Token::Value op = expr->op(); | 3771 Token::Value op = expr->op(); |
3816 VisitForStackValue(expr->left()); | 3772 VisitForStackValue(expr->left()); |
3817 switch (op) { | 3773 switch (op) { |
3818 case Token::IN: | 3774 case Token::IN: |
3819 VisitForStackValue(expr->right()); | 3775 VisitForStackValue(expr->right()); |
3820 __ CallRuntime(Runtime::kHasProperty); | 3776 CallRuntimeWithOperands(Runtime::kHasProperty); |
3821 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3777 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3822 __ CompareRoot(x0, Heap::kTrueValueRootIndex); | 3778 __ CompareRoot(x0, Heap::kTrueValueRootIndex); |
3823 Split(eq, if_true, if_false, fall_through); | 3779 Split(eq, if_true, if_false, fall_through); |
3824 break; | 3780 break; |
3825 | 3781 |
3826 case Token::INSTANCEOF: { | 3782 case Token::INSTANCEOF: { |
3827 VisitForAccumulatorValue(expr->right()); | 3783 VisitForAccumulatorValue(expr->right()); |
3828 __ Pop(x1); | 3784 PopOperand(x1); |
3829 InstanceOfStub stub(isolate()); | 3785 InstanceOfStub stub(isolate()); |
3830 __ CallStub(&stub); | 3786 __ CallStub(&stub); |
3831 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3787 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3832 __ CompareRoot(x0, Heap::kTrueValueRootIndex); | 3788 __ CompareRoot(x0, Heap::kTrueValueRootIndex); |
3833 Split(eq, if_true, if_false, fall_through); | 3789 Split(eq, if_true, if_false, fall_through); |
3834 break; | 3790 break; |
3835 } | 3791 } |
3836 | 3792 |
3837 default: { | 3793 default: { |
3838 VisitForAccumulatorValue(expr->right()); | 3794 VisitForAccumulatorValue(expr->right()); |
3839 Condition cond = CompareIC::ComputeCondition(op); | 3795 Condition cond = CompareIC::ComputeCondition(op); |
3840 | 3796 |
3841 // Pop the stack value. | 3797 // Pop the stack value. |
3842 __ Pop(x1); | 3798 PopOperand(x1); |
3843 | 3799 |
3844 JumpPatchSite patch_site(masm_); | 3800 JumpPatchSite patch_site(masm_); |
3845 if (ShouldInlineSmiCase(op)) { | 3801 if (ShouldInlineSmiCase(op)) { |
3846 Label slow_case; | 3802 Label slow_case; |
3847 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); | 3803 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); |
3848 __ Cmp(x1, x0); | 3804 __ Cmp(x1, x0); |
3849 Split(cond, if_true, if_false, NULL); | 3805 Split(cond, if_true, if_false, NULL); |
3850 __ Bind(&slow_case); | 3806 __ Bind(&slow_case); |
3851 } | 3807 } |
3852 | 3808 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3947 __ Mov(x1, cp); | 3903 __ Mov(x1, cp); |
3948 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, | 3904 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, |
3949 kLRHasBeenSaved, kDontSaveFPRegs); | 3905 kLRHasBeenSaved, kDontSaveFPRegs); |
3950 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); | 3906 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); |
3951 __ Cmp(__ StackPointer(), x1); | 3907 __ Cmp(__ StackPointer(), x1); |
3952 __ B(eq, &post_runtime); | 3908 __ B(eq, &post_runtime); |
3953 __ Push(x0); // generator object | 3909 __ Push(x0); // generator object |
3954 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 3910 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
3955 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3911 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3956 __ Bind(&post_runtime); | 3912 __ Bind(&post_runtime); |
3957 __ Pop(result_register()); | 3913 PopOperand(result_register()); |
3958 EmitReturnSequence(); | 3914 EmitReturnSequence(); |
3959 | 3915 |
3960 __ Bind(&resume); | 3916 __ Bind(&resume); |
3961 context()->Plug(result_register()); | 3917 context()->Plug(result_register()); |
3962 break; | 3918 break; |
3963 } | 3919 } |
3964 | 3920 |
3965 case Yield::kFinal: { | 3921 case Yield::kFinal: { |
3966 // Pop value from top-of-stack slot, box result into result register. | 3922 // Pop value from top-of-stack slot, box result into result register. |
| 3923 OperandStackDepthDecrement(1); |
3967 EmitCreateIteratorResult(true); | 3924 EmitCreateIteratorResult(true); |
3968 EmitUnwindAndReturn(); | 3925 EmitUnwindAndReturn(); |
3969 break; | 3926 break; |
3970 } | 3927 } |
3971 | 3928 |
3972 case Yield::kDelegating: | 3929 case Yield::kDelegating: |
3973 UNREACHABLE(); | 3930 UNREACHABLE(); |
3974 } | 3931 } |
3975 } | 3932 } |
3976 | 3933 |
3977 | 3934 |
3978 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 3935 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
3979 Expression *value, | 3936 Expression *value, |
3980 JSGeneratorObject::ResumeMode resume_mode) { | 3937 JSGeneratorObject::ResumeMode resume_mode) { |
3981 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); | 3938 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); |
3982 Register generator_object = x1; | 3939 Register generator_object = x1; |
3983 Register the_hole = x2; | 3940 Register the_hole = x2; |
3984 Register operand_stack_size = w3; | 3941 Register operand_stack_size = w3; |
3985 Register function = x4; | 3942 Register function = x4; |
3986 | 3943 |
3987 // The value stays in x0, and is ultimately read by the resumed generator, as | 3944 // The value stays in x0, and is ultimately read by the resumed generator, as |
3988 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 3945 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
3989 // is read to throw the value when the resumed generator is already closed. x1 | 3946 // is read to throw the value when the resumed generator is already closed. x1 |
3990 // will hold the generator object until the activation has been resumed. | 3947 // will hold the generator object until the activation has been resumed. |
3991 VisitForStackValue(generator); | 3948 VisitForStackValue(generator); |
3992 VisitForAccumulatorValue(value); | 3949 VisitForAccumulatorValue(value); |
3993 __ Pop(generator_object); | 3950 PopOperand(generator_object); |
3994 | 3951 |
3995 // Store input value into generator object. | 3952 // Store input value into generator object. |
3996 __ Str(result_register(), | 3953 __ Str(result_register(), |
3997 FieldMemOperand(x1, JSGeneratorObject::kInputOffset)); | 3954 FieldMemOperand(x1, JSGeneratorObject::kInputOffset)); |
3998 __ Mov(x2, result_register()); | 3955 __ Mov(x2, result_register()); |
3999 __ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x2, x3, | 3956 __ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x2, x3, |
4000 kLRHasBeenSaved, kDontSaveFPRegs); | 3957 kLRHasBeenSaved, kDontSaveFPRegs); |
4001 | 3958 |
4002 // Load suspended function and context. | 3959 // Load suspended function and context. |
4003 __ Ldr(cp, FieldMemOperand(generator_object, | 3960 __ Ldr(cp, FieldMemOperand(generator_object, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4068 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. | 4025 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. |
4069 __ Push(generator_object, result_register(), x10); | 4026 __ Push(generator_object, result_register(), x10); |
4070 __ CallRuntime(Runtime::kResumeJSGeneratorObject); | 4027 __ CallRuntime(Runtime::kResumeJSGeneratorObject); |
4071 // Not reached: the runtime call returns elsewhere. | 4028 // Not reached: the runtime call returns elsewhere. |
4072 __ Unreachable(); | 4029 __ Unreachable(); |
4073 | 4030 |
4074 __ Bind(&done); | 4031 __ Bind(&done); |
4075 context()->Plug(result_register()); | 4032 context()->Plug(result_register()); |
4076 } | 4033 } |
4077 | 4034 |
| 4035 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
| 4036 OperandStackDepthIncrement(2); |
| 4037 __ Push(reg1, reg2); |
| 4038 } |
| 4039 |
| 4040 void FullCodeGenerator::PushOperands(Register reg1, Register reg2, |
| 4041 Register reg3) { |
| 4042 OperandStackDepthIncrement(3); |
| 4043 __ Push(reg1, reg2, reg3); |
| 4044 } |
| 4045 |
| 4046 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) { |
| 4047 OperandStackDepthDecrement(2); |
| 4048 __ Pop(reg1, reg2); |
| 4049 } |
| 4050 |
| 4051 void FullCodeGenerator::EmitOperandStackDepthCheck() { |
| 4052 if (FLAG_debug_code) { |
| 4053 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp + |
| 4054 operand_stack_depth_ * kPointerSize; |
| 4055 __ Sub(x0, fp, jssp); |
| 4056 __ Cmp(x0, Operand(expected_diff)); |
| 4057 __ Assert(eq, kUnexpectedStackDepth); |
| 4058 } |
| 4059 } |
4078 | 4060 |
4079 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 4061 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
4080 Label allocate, done_allocate; | 4062 Label allocate, done_allocate; |
4081 | 4063 |
4082 // Allocate and populate an object with this form: { value: VAL, done: DONE } | 4064 // Allocate and populate an object with this form: { value: VAL, done: DONE } |
4083 | 4065 |
4084 Register result = x0; | 4066 Register result = x0; |
4085 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &allocate, TAG_OBJECT); | 4067 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &allocate, TAG_OBJECT); |
4086 __ B(&done_allocate); | 4068 __ B(&done_allocate); |
4087 | 4069 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4155 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, x10); | 4137 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, x10); |
4156 } else if (closure_scope->is_eval_scope()) { | 4138 } else if (closure_scope->is_eval_scope()) { |
4157 // Contexts created by a call to eval have the same closure as the | 4139 // Contexts created by a call to eval have the same closure as the |
4158 // context calling eval, not the anonymous closure containing the eval | 4140 // context calling eval, not the anonymous closure containing the eval |
4159 // code. Fetch it from the context. | 4141 // code. Fetch it from the context. |
4160 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); | 4142 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); |
4161 } else { | 4143 } else { |
4162 DCHECK(closure_scope->is_function_scope()); | 4144 DCHECK(closure_scope->is_function_scope()); |
4163 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4145 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
4164 } | 4146 } |
4165 __ Push(x10); | 4147 PushOperand(x10); |
4166 } | 4148 } |
4167 | 4149 |
4168 | 4150 |
4169 void FullCodeGenerator::EnterFinallyBlock() { | 4151 void FullCodeGenerator::EnterFinallyBlock() { |
4170 ASM_LOCATION("FullCodeGenerator::EnterFinallyBlock"); | 4152 ASM_LOCATION("FullCodeGenerator::EnterFinallyBlock"); |
4171 DCHECK(!result_register().is(x10)); | 4153 DCHECK(!result_register().is(x10)); |
4172 // Store pending message while executing finally block. | 4154 // Store pending message while executing finally block. |
4173 ExternalReference pending_message_obj = | 4155 ExternalReference pending_message_obj = |
4174 ExternalReference::address_of_pending_message_obj(isolate()); | 4156 ExternalReference::address_of_pending_message_obj(isolate()); |
4175 __ Mov(x10, pending_message_obj); | 4157 __ Mov(x10, pending_message_obj); |
4176 __ Ldr(x10, MemOperand(x10)); | 4158 __ Ldr(x10, MemOperand(x10)); |
4177 __ Push(x10); | 4159 PushOperand(x10); |
4178 | 4160 |
4179 ClearPendingMessage(); | 4161 ClearPendingMessage(); |
4180 } | 4162 } |
4181 | 4163 |
4182 | 4164 |
4183 void FullCodeGenerator::ExitFinallyBlock() { | 4165 void FullCodeGenerator::ExitFinallyBlock() { |
4184 ASM_LOCATION("FullCodeGenerator::ExitFinallyBlock"); | 4166 ASM_LOCATION("FullCodeGenerator::ExitFinallyBlock"); |
4185 DCHECK(!result_register().is(x10)); | 4167 DCHECK(!result_register().is(x10)); |
4186 | 4168 |
4187 // Restore pending message from stack. | 4169 // Restore pending message from stack. |
4188 __ Pop(x10); | 4170 PopOperand(x10); |
4189 ExternalReference pending_message_obj = | 4171 ExternalReference pending_message_obj = |
4190 ExternalReference::address_of_pending_message_obj(isolate()); | 4172 ExternalReference::address_of_pending_message_obj(isolate()); |
4191 __ Mov(x13, pending_message_obj); | 4173 __ Mov(x13, pending_message_obj); |
4192 __ Str(x10, MemOperand(x13)); | 4174 __ Str(x10, MemOperand(x13)); |
4193 } | 4175 } |
4194 | 4176 |
4195 | 4177 |
4196 void FullCodeGenerator::ClearPendingMessage() { | 4178 void FullCodeGenerator::ClearPendingMessage() { |
4197 DCHECK(!result_register().is(x10)); | 4179 DCHECK(!result_register().is(x10)); |
4198 ExternalReference pending_message_obj = | 4180 ExternalReference pending_message_obj = |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4321 } | 4303 } |
4322 | 4304 |
4323 return INTERRUPT; | 4305 return INTERRUPT; |
4324 } | 4306 } |
4325 | 4307 |
4326 | 4308 |
4327 } // namespace internal | 4309 } // namespace internal |
4328 } // namespace v8 | 4310 } // namespace v8 |
4329 | 4311 |
4330 #endif // V8_TARGET_ARCH_ARM64 | 4312 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |