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

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

Issue 346413004: Remove distinction between hidden and normal runtime functions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix natives fuzzing Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 bool function_in_register_x1 = true; 191 bool function_in_register_x1 = true;
192 192
193 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 193 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
194 if (heap_slots > 0) { 194 if (heap_slots > 0) {
195 // Argument to NewContext is the function, which is still in x1. 195 // Argument to NewContext is the function, which is still in x1.
196 Comment cmnt(masm_, "[ Allocate context"); 196 Comment cmnt(masm_, "[ Allocate context");
197 bool need_write_barrier = true; 197 bool need_write_barrier = true;
198 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { 198 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
199 __ Mov(x10, Operand(info->scope()->GetScopeInfo())); 199 __ Mov(x10, Operand(info->scope()->GetScopeInfo()));
200 __ Push(x1, x10); 200 __ Push(x1, x10);
201 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); 201 __ CallRuntime(Runtime::kNewGlobalContext, 2);
202 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { 202 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
203 FastNewContextStub stub(isolate(), heap_slots); 203 FastNewContextStub stub(isolate(), heap_slots);
204 __ CallStub(&stub); 204 __ CallStub(&stub);
205 // Result of FastNewContextStub is always in new space. 205 // Result of FastNewContextStub is always in new space.
206 need_write_barrier = false; 206 need_write_barrier = false;
207 } else { 207 } else {
208 __ Push(x1); 208 __ Push(x1);
209 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); 209 __ CallRuntime(Runtime::kNewFunctionContext, 1);
210 } 210 }
211 function_in_register_x1 = false; 211 function_in_register_x1 = false;
212 // Context is returned in x0. It replaces the context passed to us. 212 // Context is returned in x0. It replaces the context passed to us.
213 // It's saved in the stack and kept live in cp. 213 // It's saved in the stack and kept live in cp.
214 __ Mov(cp, x0); 214 __ Mov(cp, x0);
215 __ Str(x0, MemOperand(fp, StandardFrameConstants::kContextOffset)); 215 __ Str(x0, MemOperand(fp, StandardFrameConstants::kContextOffset));
216 // Copy any necessary parameters into the context. 216 // Copy any necessary parameters into the context.
217 int num_parameters = info->scope()->num_parameters(); 217 int num_parameters = info->scope()->num_parameters();
218 for (int i = 0; i < num_parameters; i++) { 218 for (int i = 0; i < num_parameters; i++) {
219 Variable* var = scope()->parameter(i); 219 Variable* var = scope()->parameter(i);
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 // Note: For variables we must not push an initial value (such as 852 // Note: For variables we must not push an initial value (such as
853 // 'undefined') because we may have a (legal) redeclaration and we 853 // 'undefined') because we may have a (legal) redeclaration and we
854 // must not destroy the current value. 854 // must not destroy the current value.
855 if (hole_init) { 855 if (hole_init) {
856 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); 856 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex);
857 __ Push(cp, x2, x1, x0); 857 __ Push(cp, x2, x1, x0);
858 } else { 858 } else {
859 // Pushing 0 (xzr) indicates no initial value. 859 // Pushing 0 (xzr) indicates no initial value.
860 __ Push(cp, x2, x1, xzr); 860 __ Push(cp, x2, x1, xzr);
861 } 861 }
862 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); 862 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
863 break; 863 break;
864 } 864 }
865 } 865 }
866 } 866 }
867 867
868 868
869 void FullCodeGenerator::VisitFunctionDeclaration( 869 void FullCodeGenerator::VisitFunctionDeclaration(
870 FunctionDeclaration* declaration) { 870 FunctionDeclaration* declaration) {
871 VariableProxy* proxy = declaration->proxy(); 871 VariableProxy* proxy = declaration->proxy();
872 Variable* variable = proxy->var(); 872 Variable* variable = proxy->var();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 break; 908 break;
909 } 909 }
910 910
911 case Variable::LOOKUP: { 911 case Variable::LOOKUP: {
912 Comment cmnt(masm_, "[ Function Declaration"); 912 Comment cmnt(masm_, "[ Function Declaration");
913 __ Mov(x2, Operand(variable->name())); 913 __ Mov(x2, Operand(variable->name()));
914 __ Mov(x1, Smi::FromInt(NONE)); 914 __ Mov(x1, Smi::FromInt(NONE));
915 __ Push(cp, x2, x1); 915 __ Push(cp, x2, x1);
916 // Push initial value for function declaration. 916 // Push initial value for function declaration.
917 VisitForStackValue(declaration->fun()); 917 VisitForStackValue(declaration->fun());
918 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); 918 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
919 break; 919 break;
920 } 920 }
921 } 921 }
922 } 922 }
923 923
924 924
925 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { 925 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
926 Variable* variable = declaration->proxy()->var(); 926 Variable* variable = declaration->proxy()->var();
927 ASSERT(variable->location() == Variable::CONTEXT); 927 ASSERT(variable->location() == Variable::CONTEXT);
928 ASSERT(variable->interface()->IsFrozen()); 928 ASSERT(variable->interface()->IsFrozen());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 983
984 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 984 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
985 // Call the runtime to declare the globals. 985 // Call the runtime to declare the globals.
986 __ Mov(x11, Operand(pairs)); 986 __ Mov(x11, Operand(pairs));
987 Register flags = xzr; 987 Register flags = xzr;
988 if (Smi::FromInt(DeclareGlobalsFlags())) { 988 if (Smi::FromInt(DeclareGlobalsFlags())) {
989 flags = x10; 989 flags = x10;
990 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags())); 990 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags()));
991 } 991 }
992 __ Push(cp, x11, flags); 992 __ Push(cp, x11, flags);
993 __ CallRuntime(Runtime::kHiddenDeclareGlobals, 3); 993 __ CallRuntime(Runtime::kDeclareGlobals, 3);
994 // Return value is ignored. 994 // Return value is ignored.
995 } 995 }
996 996
997 997
998 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 998 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
999 // Call the runtime to declare the modules. 999 // Call the runtime to declare the modules.
1000 __ Push(descriptions); 1000 __ Push(descriptions);
1001 __ CallRuntime(Runtime::kHiddenDeclareModules, 1); 1001 __ CallRuntime(Runtime::kDeclareModules, 1);
1002 // Return value is ignored. 1002 // Return value is ignored.
1003 } 1003 }
1004 1004
1005 1005
1006 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 1006 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
1007 ASM_LOCATION("FullCodeGenerator::VisitSwitchStatement"); 1007 ASM_LOCATION("FullCodeGenerator::VisitSwitchStatement");
1008 Comment cmnt(masm_, "[ SwitchStatement"); 1008 Comment cmnt(masm_, "[ SwitchStatement");
1009 Breakable nested_statement(this, stmt); 1009 Breakable nested_statement(this, stmt);
1010 SetStatementPosition(stmt); 1010 SetStatementPosition(stmt);
1011 1011
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 FastNewClosureStub stub(isolate(), 1331 FastNewClosureStub stub(isolate(),
1332 info->strict_mode(), 1332 info->strict_mode(),
1333 info->is_generator()); 1333 info->is_generator());
1334 __ Mov(x2, Operand(info)); 1334 __ Mov(x2, Operand(info));
1335 __ CallStub(&stub); 1335 __ CallStub(&stub);
1336 } else { 1336 } else {
1337 __ Mov(x11, Operand(info)); 1337 __ Mov(x11, Operand(info));
1338 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex 1338 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex
1339 : Heap::kFalseValueRootIndex); 1339 : Heap::kFalseValueRootIndex);
1340 __ Push(cp, x11, x10); 1340 __ Push(cp, x11, x10);
1341 __ CallRuntime(Runtime::kHiddenNewClosure, 3); 1341 __ CallRuntime(Runtime::kNewClosure, 3);
1342 } 1342 }
1343 context()->Plug(x0); 1343 context()->Plug(x0);
1344 } 1344 }
1345 1345
1346 1346
1347 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1347 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1348 Comment cmnt(masm_, "[ VariableProxy"); 1348 Comment cmnt(masm_, "[ VariableProxy");
1349 EmitVariableLoad(expr); 1349 EmitVariableLoad(expr);
1350 } 1350 }
1351 1351
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 Variable* local = var->local_if_not_shadowed(); 1447 Variable* local = var->local_if_not_shadowed();
1448 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow)); 1448 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow));
1449 if (local->mode() == LET || local->mode() == CONST || 1449 if (local->mode() == LET || local->mode() == CONST ||
1450 local->mode() == CONST_LEGACY) { 1450 local->mode() == CONST_LEGACY) {
1451 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done); 1451 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done);
1452 if (local->mode() == CONST_LEGACY) { 1452 if (local->mode() == CONST_LEGACY) {
1453 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1453 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1454 } else { // LET || CONST 1454 } else { // LET || CONST
1455 __ Mov(x0, Operand(var->name())); 1455 __ Mov(x0, Operand(var->name()));
1456 __ Push(x0); 1456 __ Push(x0);
1457 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); 1457 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1458 } 1458 }
1459 } 1459 }
1460 __ B(done); 1460 __ B(done);
1461 } 1461 }
1462 } 1462 }
1463 1463
1464 1464
1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1466 // Record position before possible IC call. 1466 // Record position before possible IC call.
1467 SetSourcePosition(proxy->position()); 1467 SetSourcePosition(proxy->position());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 if (!skip_init_check) { 1525 if (!skip_init_check) {
1526 // Let and const need a read barrier. 1526 // Let and const need a read barrier.
1527 GetVar(x0, var); 1527 GetVar(x0, var);
1528 Label done; 1528 Label done;
1529 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done); 1529 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done);
1530 if (var->mode() == LET || var->mode() == CONST) { 1530 if (var->mode() == LET || var->mode() == CONST) {
1531 // Throw a reference error when using an uninitialized let/const 1531 // Throw a reference error when using an uninitialized let/const
1532 // binding in harmony mode. 1532 // binding in harmony mode.
1533 __ Mov(x0, Operand(var->name())); 1533 __ Mov(x0, Operand(var->name()));
1534 __ Push(x0); 1534 __ Push(x0);
1535 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); 1535 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1536 __ Bind(&done); 1536 __ Bind(&done);
1537 } else { 1537 } else {
1538 // Uninitalized const bindings outside of harmony mode are unholed. 1538 // Uninitalized const bindings outside of harmony mode are unholed.
1539 ASSERT(var->mode() == CONST_LEGACY); 1539 ASSERT(var->mode() == CONST_LEGACY);
1540 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1540 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1541 __ Bind(&done); 1541 __ Bind(&done);
1542 } 1542 }
1543 context()->Plug(x0); 1543 context()->Plug(x0);
1544 break; 1544 break;
1545 } 1545 }
1546 } 1546 }
1547 context()->Plug(var); 1547 context()->Plug(var);
1548 break; 1548 break;
1549 } 1549 }
1550 1550
1551 case Variable::LOOKUP: { 1551 case Variable::LOOKUP: {
1552 Label done, slow; 1552 Label done, slow;
1553 // Generate code for loading from variables potentially shadowed by 1553 // Generate code for loading from variables potentially shadowed by
1554 // eval-introduced variables. 1554 // eval-introduced variables.
1555 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); 1555 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done);
1556 __ Bind(&slow); 1556 __ Bind(&slow);
1557 Comment cmnt(masm_, "Lookup variable"); 1557 Comment cmnt(masm_, "Lookup variable");
1558 __ Mov(x1, Operand(var->name())); 1558 __ Mov(x1, Operand(var->name()));
1559 __ Push(cp, x1); // Context and name. 1559 __ Push(cp, x1); // Context and name.
1560 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); 1560 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1561 __ Bind(&done); 1561 __ Bind(&done);
1562 context()->Plug(x0); 1562 context()->Plug(x0);
1563 break; 1563 break;
1564 } 1564 }
1565 } 1565 }
1566 } 1566 }
1567 1567
1568 1568
1569 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1569 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1570 Comment cmnt(masm_, "[ RegExpLiteral"); 1570 Comment cmnt(masm_, "[ RegExpLiteral");
(...skipping 11 matching lines...) Expand all
1582 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 1582 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
1583 __ Ldr(x5, FieldMemOperand(x4, literal_offset)); 1583 __ Ldr(x5, FieldMemOperand(x4, literal_offset));
1584 __ JumpIfNotRoot(x5, Heap::kUndefinedValueRootIndex, &materialized); 1584 __ JumpIfNotRoot(x5, Heap::kUndefinedValueRootIndex, &materialized);
1585 1585
1586 // Create regexp literal using runtime function. 1586 // Create regexp literal using runtime function.
1587 // Result will be in x0. 1587 // Result will be in x0.
1588 __ Mov(x3, Smi::FromInt(expr->literal_index())); 1588 __ Mov(x3, Smi::FromInt(expr->literal_index()));
1589 __ Mov(x2, Operand(expr->pattern())); 1589 __ Mov(x2, Operand(expr->pattern()));
1590 __ Mov(x1, Operand(expr->flags())); 1590 __ Mov(x1, Operand(expr->flags()));
1591 __ Push(x4, x3, x2, x1); 1591 __ Push(x4, x3, x2, x1);
1592 __ CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4); 1592 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1593 __ Mov(x5, x0); 1593 __ Mov(x5, x0);
1594 1594
1595 __ Bind(&materialized); 1595 __ Bind(&materialized);
1596 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 1596 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1597 Label allocated, runtime_allocate; 1597 Label allocated, runtime_allocate;
1598 __ Allocate(size, x0, x2, x3, &runtime_allocate, TAG_OBJECT); 1598 __ Allocate(size, x0, x2, x3, &runtime_allocate, TAG_OBJECT);
1599 __ B(&allocated); 1599 __ B(&allocated);
1600 1600
1601 __ Bind(&runtime_allocate); 1601 __ Bind(&runtime_allocate);
1602 __ Mov(x10, Smi::FromInt(size)); 1602 __ Mov(x10, Smi::FromInt(size));
1603 __ Push(x5, x10); 1603 __ Push(x5, x10);
1604 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); 1604 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1605 __ Pop(x5); 1605 __ Pop(x5);
1606 1606
1607 __ Bind(&allocated); 1607 __ Bind(&allocated);
1608 // After this, registers are used as follows: 1608 // After this, registers are used as follows:
1609 // x0: Newly allocated regexp. 1609 // x0: Newly allocated regexp.
1610 // x5: Materialized regexp. 1610 // x5: Materialized regexp.
1611 // x10, x11, x12: temps. 1611 // x10, x11, x12: temps.
1612 __ CopyFields(x0, x5, CPURegList(x10, x11, x12), size / kPointerSize); 1612 __ CopyFields(x0, x5, CPURegList(x10, x11, x12), size / kPointerSize);
1613 context()->Plug(x0); 1613 context()->Plug(x0);
1614 } 1614 }
(...skipping 25 matching lines...) Expand all
1640 ? ObjectLiteral::kHasFunction 1640 ? ObjectLiteral::kHasFunction
1641 : ObjectLiteral::kNoFlags; 1641 : ObjectLiteral::kNoFlags;
1642 __ Mov(x0, Smi::FromInt(flags)); 1642 __ Mov(x0, Smi::FromInt(flags));
1643 int properties_count = constant_properties->length() / 2; 1643 int properties_count = constant_properties->length() / 2;
1644 const int max_cloned_properties = 1644 const int max_cloned_properties =
1645 FastCloneShallowObjectStub::kMaximumClonedProperties; 1645 FastCloneShallowObjectStub::kMaximumClonedProperties;
1646 if (expr->may_store_doubles() || expr->depth() > 1 || 1646 if (expr->may_store_doubles() || expr->depth() > 1 ||
1647 masm()->serializer_enabled() || flags != ObjectLiteral::kFastElements || 1647 masm()->serializer_enabled() || flags != ObjectLiteral::kFastElements ||
1648 properties_count > max_cloned_properties) { 1648 properties_count > max_cloned_properties) {
1649 __ Push(x3, x2, x1, x0); 1649 __ Push(x3, x2, x1, x0);
1650 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); 1650 __ CallRuntime(Runtime::kCreateObjectLiteral, 4);
1651 } else { 1651 } else {
1652 FastCloneShallowObjectStub stub(isolate(), properties_count); 1652 FastCloneShallowObjectStub stub(isolate(), properties_count);
1653 __ CallStub(&stub); 1653 __ CallStub(&stub);
1654 } 1654 }
1655 1655
1656 // If result_saved is true the result is on top of the stack. If 1656 // If result_saved is true the result is on top of the stack. If
1657 // result_saved is false the result is in x0. 1657 // result_saved is false the result is in x0.
1658 bool result_saved = false; 1658 bool result_saved = false;
1659 1659
1660 // Mark all computed expressions that are bound to a key that 1660 // Mark all computed expressions that are bound to a key that
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1780 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1781 } 1781 }
1782 1782
1783 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1783 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1784 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset)); 1784 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset));
1785 __ Mov(x2, Smi::FromInt(expr->literal_index())); 1785 __ Mov(x2, Smi::FromInt(expr->literal_index()));
1786 __ Mov(x1, Operand(constant_elements)); 1786 __ Mov(x1, Operand(constant_elements));
1787 if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) { 1787 if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) {
1788 __ Mov(x0, Smi::FromInt(flags)); 1788 __ Mov(x0, Smi::FromInt(flags));
1789 __ Push(x3, x2, x1, x0); 1789 __ Push(x3, x2, x1, x0);
1790 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); 1790 __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
1791 } else { 1791 } else {
1792 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1792 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1793 __ CallStub(&stub); 1793 __ CallStub(&stub);
1794 } 1794 }
1795 1795
1796 bool result_saved = false; // Is the result saved to the stack? 1796 bool result_saved = false; // Is the result saved to the stack?
1797 1797
1798 // Emit code to evaluate all the non-constant subexpressions and to store 1798 // Emit code to evaluate all the non-constant subexpressions and to store
1799 // them into the newly cloned array. 1799 // them into the newly cloned array.
1800 for (int i = 0; i < length; i++) { 1800 for (int i = 0; i < length; i++) {
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
2142 2142
2143 void FullCodeGenerator::EmitCallStoreContextSlot( 2143 void FullCodeGenerator::EmitCallStoreContextSlot(
2144 Handle<String> name, StrictMode strict_mode) { 2144 Handle<String> name, StrictMode strict_mode) {
2145 __ Mov(x11, Operand(name)); 2145 __ Mov(x11, Operand(name));
2146 __ Mov(x10, Smi::FromInt(strict_mode)); 2146 __ Mov(x10, Smi::FromInt(strict_mode));
2147 // jssp[0] : mode. 2147 // jssp[0] : mode.
2148 // jssp[8] : name. 2148 // jssp[8] : name.
2149 // jssp[16] : context. 2149 // jssp[16] : context.
2150 // jssp[24] : value. 2150 // jssp[24] : value.
2151 __ Push(x0, cp, x11, x10); 2151 __ Push(x0, cp, x11, x10);
2152 __ CallRuntime(Runtime::kHiddenStoreContextSlot, 4); 2152 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2153 } 2153 }
2154 2154
2155 2155
2156 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2156 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2157 Token::Value op) { 2157 Token::Value op) {
2158 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); 2158 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment");
2159 if (var->IsUnallocated()) { 2159 if (var->IsUnallocated()) {
2160 // Global var, const, or let. 2160 // Global var, const, or let.
2161 __ Mov(x2, Operand(var->name())); 2161 __ Mov(x2, Operand(var->name()));
2162 __ Ldr(x1, GlobalObjectMemOperand()); 2162 __ Ldr(x1, GlobalObjectMemOperand());
2163 CallStoreIC(); 2163 CallStoreIC();
2164 2164
2165 } else if (op == Token::INIT_CONST_LEGACY) { 2165 } else if (op == Token::INIT_CONST_LEGACY) {
2166 // Const initializers need a write barrier. 2166 // Const initializers need a write barrier.
2167 ASSERT(!var->IsParameter()); // No const parameters. 2167 ASSERT(!var->IsParameter()); // No const parameters.
2168 if (var->IsLookupSlot()) { 2168 if (var->IsLookupSlot()) {
2169 __ Push(x0); 2169 __ Push(x0);
2170 __ Mov(x0, Operand(var->name())); 2170 __ Mov(x0, Operand(var->name()));
2171 __ Push(cp, x0); // Context and name. 2171 __ Push(cp, x0); // Context and name.
2172 __ CallRuntime(Runtime::kHiddenInitializeConstContextSlot, 3); 2172 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
2173 } else { 2173 } else {
2174 ASSERT(var->IsStackLocal() || var->IsContextSlot()); 2174 ASSERT(var->IsStackLocal() || var->IsContextSlot());
2175 Label skip; 2175 Label skip;
2176 MemOperand location = VarOperand(var, x1); 2176 MemOperand location = VarOperand(var, x1);
2177 __ Ldr(x10, location); 2177 __ Ldr(x10, location);
2178 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); 2178 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip);
2179 EmitStoreToStackLocalOrContextSlot(var, location); 2179 EmitStoreToStackLocalOrContextSlot(var, location);
2180 __ Bind(&skip); 2180 __ Bind(&skip);
2181 } 2181 }
2182 2182
2183 } else if (var->mode() == LET && op != Token::INIT_LET) { 2183 } else if (var->mode() == LET && op != Token::INIT_LET) {
2184 // Non-initializing assignment to let variable needs a write barrier. 2184 // Non-initializing assignment to let variable needs a write barrier.
2185 if (var->IsLookupSlot()) { 2185 if (var->IsLookupSlot()) {
2186 EmitCallStoreContextSlot(var->name(), strict_mode()); 2186 EmitCallStoreContextSlot(var->name(), strict_mode());
2187 } else { 2187 } else {
2188 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2188 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2189 Label assign; 2189 Label assign;
2190 MemOperand location = VarOperand(var, x1); 2190 MemOperand location = VarOperand(var, x1);
2191 __ Ldr(x10, location); 2191 __ Ldr(x10, location);
2192 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); 2192 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign);
2193 __ Mov(x10, Operand(var->name())); 2193 __ Mov(x10, Operand(var->name()));
2194 __ Push(x10); 2194 __ Push(x10);
2195 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); 2195 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2196 // Perform the assignment. 2196 // Perform the assignment.
2197 __ Bind(&assign); 2197 __ Bind(&assign);
2198 EmitStoreToStackLocalOrContextSlot(var, location); 2198 EmitStoreToStackLocalOrContextSlot(var, location);
2199 } 2199 }
2200 2200
2201 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { 2201 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2202 // Assignment to var or initializing assignment to let/const 2202 // Assignment to var or initializing assignment to let/const
2203 // in harmony mode. 2203 // in harmony mode.
2204 if (var->IsLookupSlot()) { 2204 if (var->IsLookupSlot()) {
2205 EmitCallStoreContextSlot(var->name(), strict_mode()); 2205 EmitCallStoreContextSlot(var->name(), strict_mode());
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 2384
2385 // Prepare to push the language mode. 2385 // Prepare to push the language mode.
2386 __ Mov(x10, Smi::FromInt(strict_mode())); 2386 __ Mov(x10, Smi::FromInt(strict_mode()));
2387 // Prepare to push the start position of the scope the calls resides in. 2387 // Prepare to push the start position of the scope the calls resides in.
2388 __ Mov(x11, Smi::FromInt(scope()->start_position())); 2388 __ Mov(x11, Smi::FromInt(scope()->start_position()));
2389 2389
2390 // Push. 2390 // Push.
2391 __ Push(x10, x11); 2391 __ Push(x10, x11);
2392 2392
2393 // Do the runtime call. 2393 // Do the runtime call.
2394 __ CallRuntime(Runtime::kHiddenResolvePossiblyDirectEval, 5); 2394 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2395 } 2395 }
2396 2396
2397 2397
2398 void FullCodeGenerator::VisitCall(Call* expr) { 2398 void FullCodeGenerator::VisitCall(Call* expr) {
2399 #ifdef DEBUG 2399 #ifdef DEBUG
2400 // We want to verify that RecordJSReturnSite gets called on all paths 2400 // We want to verify that RecordJSReturnSite gets called on all paths
2401 // through this function. Avoid early returns. 2401 // through this function. Avoid early returns.
2402 expr->return_is_recorded_ = false; 2402 expr->return_is_recorded_ = false;
2403 #endif 2403 #endif
2404 2404
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 // by eval-introduced variables. 2461 // by eval-introduced variables.
2462 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2462 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2463 } 2463 }
2464 2464
2465 __ Bind(&slow); 2465 __ Bind(&slow);
2466 // Call the runtime to find the function to call (returned in x0) 2466 // Call the runtime to find the function to call (returned in x0)
2467 // and the object holding it (returned in x1). 2467 // and the object holding it (returned in x1).
2468 __ Push(context_register()); 2468 __ Push(context_register());
2469 __ Mov(x10, Operand(proxy->name())); 2469 __ Mov(x10, Operand(proxy->name()));
2470 __ Push(x10); 2470 __ Push(x10);
2471 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); 2471 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2472 __ Push(x0, x1); // Receiver, function. 2472 __ Push(x0, x1); // Receiver, function.
2473 2473
2474 // If fast case code has been generated, emit code to push the 2474 // If fast case code has been generated, emit code to push the
2475 // function and receiver and have the slow path jump around this 2475 // function and receiver and have the slow path jump around this
2476 // code. 2476 // code.
2477 if (done.is_linked()) { 2477 if (done.is_linked()) {
2478 Label call; 2478 Label call;
2479 __ B(&call); 2479 __ B(&call);
2480 __ Bind(&done); 2480 __ Bind(&done);
2481 // Push function. 2481 // Push function.
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
3109 __ B(&done); 3109 __ B(&done);
3110 } 3110 }
3111 3111
3112 __ Bind(&runtime); 3112 __ Bind(&runtime);
3113 __ Mov(x1, index); 3113 __ Mov(x1, index);
3114 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 3114 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
3115 __ B(&done); 3115 __ B(&done);
3116 } 3116 }
3117 3117
3118 __ Bind(&not_date_object); 3118 __ Bind(&not_date_object);
3119 __ CallRuntime(Runtime::kHiddenThrowNotDateError, 0); 3119 __ CallRuntime(Runtime::kThrowNotDateError, 0);
3120 __ Bind(&done); 3120 __ Bind(&done);
3121 context()->Plug(x0); 3121 context()->Plug(x0);
3122 } 3122 }
3123 3123
3124 3124
3125 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 3125 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3126 ZoneList<Expression*>* args = expr->arguments(); 3126 ZoneList<Expression*>* args = expr->arguments();
3127 ASSERT_EQ(3, args->length()); 3127 ASSERT_EQ(3, args->length());
3128 3128
3129 Register string = x0; 3129 Register string = x0;
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
3456 3456
3457 // Load the key and data from the cache. 3457 // Load the key and data from the cache.
3458 __ Ldp(x2, x3, MemOperand(x3)); 3458 __ Ldp(x2, x3, MemOperand(x3));
3459 3459
3460 __ Cmp(key, x2); 3460 __ Cmp(key, x2);
3461 __ CmovX(x0, x3, eq); 3461 __ CmovX(x0, x3, eq);
3462 __ B(eq, &done); 3462 __ B(eq, &done);
3463 3463
3464 // Call runtime to perform the lookup. 3464 // Call runtime to perform the lookup.
3465 __ Push(cache, key); 3465 __ Push(cache, key);
3466 __ CallRuntime(Runtime::kHiddenGetFromCache, 2); 3466 __ CallRuntime(Runtime::kGetFromCache, 2);
3467 3467
3468 __ Bind(&done); 3468 __ Bind(&done);
3469 context()->Plug(x0); 3469 context()->Plug(x0);
3470 } 3470 }
3471 3471
3472 3472
3473 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3473 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3474 ZoneList<Expression*>* args = expr->arguments(); 3474 ZoneList<Expression*>* args = expr->arguments();
3475 VisitForAccumulatorValue(args->at(0)); 3475 VisitForAccumulatorValue(args->at(0));
3476 3476
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
3814 context()->Plug(x0); 3814 context()->Plug(x0);
3815 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 3815 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
3816 // Result of deleting non-global, non-dynamic variables is false. 3816 // Result of deleting non-global, non-dynamic variables is false.
3817 // The subexpression does not have side effects. 3817 // The subexpression does not have side effects.
3818 context()->Plug(var->is_this()); 3818 context()->Plug(var->is_this());
3819 } else { 3819 } else {
3820 // Non-global variable. Call the runtime to try to delete from the 3820 // Non-global variable. Call the runtime to try to delete from the
3821 // context where the variable was introduced. 3821 // context where the variable was introduced.
3822 __ Mov(x2, Operand(var->name())); 3822 __ Mov(x2, Operand(var->name()));
3823 __ Push(context_register(), x2); 3823 __ Push(context_register(), x2);
3824 __ CallRuntime(Runtime::kHiddenDeleteContextSlot, 2); 3824 __ CallRuntime(Runtime::kDeleteContextSlot, 2);
3825 context()->Plug(x0); 3825 context()->Plug(x0);
3826 } 3826 }
3827 } else { 3827 } else {
3828 // Result of deleting non-property, non-variable reference is true. 3828 // Result of deleting non-property, non-variable reference is true.
3829 // The subexpression may have side effects. 3829 // The subexpression may have side effects.
3830 VisitForEffect(expr->expression()); 3830 VisitForEffect(expr->expression());
3831 context()->Plug(true); 3831 context()->Plug(true);
3832 } 3832 }
3833 break; 3833 break;
3834 break; 3834 break;
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
4094 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4094 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4095 Label done, slow; 4095 Label done, slow;
4096 4096
4097 // Generate code for loading from variables potentially shadowed 4097 // Generate code for loading from variables potentially shadowed
4098 // by eval-introduced variables. 4098 // by eval-introduced variables.
4099 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); 4099 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done);
4100 4100
4101 __ Bind(&slow); 4101 __ Bind(&slow);
4102 __ Mov(x0, Operand(proxy->name())); 4102 __ Mov(x0, Operand(proxy->name()));
4103 __ Push(cp, x0); 4103 __ Push(cp, x0);
4104 __ CallRuntime(Runtime::kHiddenLoadContextSlotNoReferenceError, 2); 4104 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
4105 PrepareForBailout(expr, TOS_REG); 4105 PrepareForBailout(expr, TOS_REG);
4106 __ Bind(&done); 4106 __ Bind(&done);
4107 4107
4108 context()->Plug(x0); 4108 context()->Plug(x0);
4109 } else { 4109 } else {
4110 // This expression cannot throw a reference error at the top level. 4110 // This expression cannot throw a reference error at the top level.
4111 VisitInDuplicateContext(expr); 4111 VisitInDuplicateContext(expr);
4112 } 4112 }
4113 } 4113 }
4114 4114
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
4346 __ Mov(x1, Smi::FromInt(continuation.pos())); 4346 __ Mov(x1, Smi::FromInt(continuation.pos()));
4347 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); 4347 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
4348 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); 4348 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset));
4349 __ Mov(x1, cp); 4349 __ Mov(x1, cp);
4350 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, 4350 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2,
4351 kLRHasBeenSaved, kDontSaveFPRegs); 4351 kLRHasBeenSaved, kDontSaveFPRegs);
4352 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); 4352 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset);
4353 __ Cmp(__ StackPointer(), x1); 4353 __ Cmp(__ StackPointer(), x1);
4354 __ B(eq, &post_runtime); 4354 __ B(eq, &post_runtime);
4355 __ Push(x0); // generator object 4355 __ Push(x0); // generator object
4356 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); 4356 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
4357 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4357 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4358 __ Bind(&post_runtime); 4358 __ Bind(&post_runtime);
4359 __ Pop(result_register()); 4359 __ Pop(result_register());
4360 EmitReturnSequence(); 4360 EmitReturnSequence();
4361 4361
4362 __ Bind(&resume); 4362 __ Bind(&resume);
4363 context()->Plug(result_register()); 4363 context()->Plug(result_register());
4364 break; 4364 break;
4365 } 4365 }
4366 4366
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4417 const int generator_object_depth = kPointerSize + handler_size; 4417 const int generator_object_depth = kPointerSize + handler_size;
4418 __ Peek(x0, generator_object_depth); 4418 __ Peek(x0, generator_object_depth);
4419 __ Push(x0); // g 4419 __ Push(x0); // g
4420 ASSERT((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos())); 4420 ASSERT((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos()));
4421 __ Mov(x1, Smi::FromInt(l_continuation.pos())); 4421 __ Mov(x1, Smi::FromInt(l_continuation.pos()));
4422 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); 4422 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
4423 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); 4423 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset));
4424 __ Mov(x1, cp); 4424 __ Mov(x1, cp);
4425 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, 4425 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2,
4426 kLRHasBeenSaved, kDontSaveFPRegs); 4426 kLRHasBeenSaved, kDontSaveFPRegs);
4427 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); 4427 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
4428 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4428 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4429 __ Pop(x0); // result 4429 __ Pop(x0); // result
4430 EmitReturnSequence(); 4430 EmitReturnSequence();
4431 __ Bind(&l_resume); // received in x0 4431 __ Bind(&l_resume); // received in x0
4432 __ PopTryHandler(); 4432 __ PopTryHandler();
4433 4433
4434 // receiver = iter; f = 'next'; arg = received; 4434 // receiver = iter; f = 'next'; arg = received;
4435 __ Bind(&l_next); 4435 __ Bind(&l_next);
4436 __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next" 4436 __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next"
4437 __ Peek(x3, 1 * kPointerSize); // iter 4437 __ Peek(x3, 1 * kPointerSize); // iter
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4476 Expression *value, 4476 Expression *value,
4477 JSGeneratorObject::ResumeMode resume_mode) { 4477 JSGeneratorObject::ResumeMode resume_mode) {
4478 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); 4478 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume");
4479 Register value_reg = x0; 4479 Register value_reg = x0;
4480 Register generator_object = x1; 4480 Register generator_object = x1;
4481 Register the_hole = x2; 4481 Register the_hole = x2;
4482 Register operand_stack_size = w3; 4482 Register operand_stack_size = w3;
4483 Register function = x4; 4483 Register function = x4;
4484 4484
4485 // The value stays in x0, and is ultimately read by the resumed generator, as 4485 // The value stays in x0, and is ultimately read by the resumed generator, as
4486 // if CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject) returned it. Or it 4486 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
4487 // is read to throw the value when the resumed generator is already closed. r1 4487 // is read to throw the value when the resumed generator is already closed. r1
4488 // will hold the generator object until the activation has been resumed. 4488 // will hold the generator object until the activation has been resumed.
4489 VisitForStackValue(generator); 4489 VisitForStackValue(generator);
4490 VisitForAccumulatorValue(value); 4490 VisitForAccumulatorValue(value);
4491 __ Pop(generator_object); 4491 __ Pop(generator_object);
4492 4492
4493 // Check generator state. 4493 // Check generator state.
4494 Label wrong_state, closed_state, done; 4494 Label wrong_state, closed_state, done;
4495 __ Ldr(x10, FieldMemOperand(generator_object, 4495 __ Ldr(x10, FieldMemOperand(generator_object,
4496 JSGeneratorObject::kContinuationOffset)); 4496 JSGeneratorObject::kContinuationOffset));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4558 4558
4559 __ Bind(&slow_resume); 4559 __ Bind(&slow_resume);
4560 } 4560 }
4561 4561
4562 // Otherwise, we push holes for the operand stack and call the runtime to fix 4562 // Otherwise, we push holes for the operand stack and call the runtime to fix
4563 // up the stack and the handlers. 4563 // up the stack and the handlers.
4564 __ PushMultipleTimes(the_hole, operand_stack_size); 4564 __ PushMultipleTimes(the_hole, operand_stack_size);
4565 4565
4566 __ Mov(x10, Smi::FromInt(resume_mode)); 4566 __ Mov(x10, Smi::FromInt(resume_mode));
4567 __ Push(generator_object, result_register(), x10); 4567 __ Push(generator_object, result_register(), x10);
4568 __ CallRuntime(Runtime::kHiddenResumeJSGeneratorObject, 3); 4568 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
4569 // Not reached: the runtime call returns elsewhere. 4569 // Not reached: the runtime call returns elsewhere.
4570 __ Unreachable(); 4570 __ Unreachable();
4571 4571
4572 // Reach here when generator is closed. 4572 // Reach here when generator is closed.
4573 __ Bind(&closed_state); 4573 __ Bind(&closed_state);
4574 if (resume_mode == JSGeneratorObject::NEXT) { 4574 if (resume_mode == JSGeneratorObject::NEXT) {
4575 // Return completed iterator result when generator is closed. 4575 // Return completed iterator result when generator is closed.
4576 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); 4576 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
4577 __ Push(x10); 4577 __ Push(x10);
4578 // Pop value from top-of-stack slot; box result into result register. 4578 // Pop value from top-of-stack slot; box result into result register.
4579 EmitCreateIteratorResult(true); 4579 EmitCreateIteratorResult(true);
4580 } else { 4580 } else {
4581 // Throw the provided value. 4581 // Throw the provided value.
4582 __ Push(value_reg); 4582 __ Push(value_reg);
4583 __ CallRuntime(Runtime::kHiddenThrow, 1); 4583 __ CallRuntime(Runtime::kThrow, 1);
4584 } 4584 }
4585 __ B(&done); 4585 __ B(&done);
4586 4586
4587 // Throw error if we attempt to operate on a running generator. 4587 // Throw error if we attempt to operate on a running generator.
4588 __ Bind(&wrong_state); 4588 __ Bind(&wrong_state);
4589 __ Push(generator_object); 4589 __ Push(generator_object);
4590 __ CallRuntime(Runtime::kHiddenThrowGeneratorStateError, 1); 4590 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
4591 4591
4592 __ Bind(&done); 4592 __ Bind(&done);
4593 context()->Plug(result_register()); 4593 context()->Plug(result_register());
4594 } 4594 }
4595 4595
4596 4596
4597 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 4597 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
4598 Label gc_required; 4598 Label gc_required;
4599 Label allocated; 4599 Label allocated;
4600 4600
4601 Handle<Map> map(isolate()->native_context()->iterator_result_map()); 4601 Handle<Map> map(isolate()->native_context()->iterator_result_map());
4602 4602
4603 // Allocate and populate an object with this form: { value: VAL, done: DONE } 4603 // Allocate and populate an object with this form: { value: VAL, done: DONE }
4604 4604
4605 Register result = x0; 4605 Register result = x0;
4606 __ Allocate(map->instance_size(), result, x10, x11, &gc_required, TAG_OBJECT); 4606 __ Allocate(map->instance_size(), result, x10, x11, &gc_required, TAG_OBJECT);
4607 __ B(&allocated); 4607 __ B(&allocated);
4608 4608
4609 __ Bind(&gc_required); 4609 __ Bind(&gc_required);
4610 __ Push(Smi::FromInt(map->instance_size())); 4610 __ Push(Smi::FromInt(map->instance_size()));
4611 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); 4611 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
4612 __ Ldr(context_register(), 4612 __ Ldr(context_register(),
4613 MemOperand(fp, StandardFrameConstants::kContextOffset)); 4613 MemOperand(fp, StandardFrameConstants::kContextOffset));
4614 4614
4615 __ Bind(&allocated); 4615 __ Bind(&allocated);
4616 Register map_reg = x1; 4616 Register map_reg = x1;
4617 Register result_value = x2; 4617 Register result_value = x2;
4618 Register boolean_done = x3; 4618 Register boolean_done = x3;
4619 Register empty_fixed_array = x4; 4619 Register empty_fixed_array = x4;
4620 Register untagged_result = x5; 4620 Register untagged_result = x5;
4621 __ Mov(map_reg, Operand(map)); 4621 __ Mov(map_reg, Operand(map));
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
4886 return previous_; 4886 return previous_;
4887 } 4887 }
4888 4888
4889 4889
4890 #undef __ 4890 #undef __
4891 4891
4892 4892
4893 } } // namespace v8::internal 4893 } } // namespace v8::internal
4894 4894
4895 #endif // V8_TARGET_ARCH_ARM64 4895 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698