| 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 #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 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 context()->Plug(x0); | 1344 context()->Plug(x0); |
| 1345 } | 1345 } |
| 1346 | 1346 |
| 1347 | 1347 |
| 1348 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1348 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1349 Comment cmnt(masm_, "[ VariableProxy"); | 1349 Comment cmnt(masm_, "[ VariableProxy"); |
| 1350 EmitVariableLoad(expr); | 1350 EmitVariableLoad(expr); |
| 1351 } | 1351 } |
| 1352 | 1352 |
| 1353 | 1353 |
| 1354 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, | 1354 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1355 TypeofState typeof_state, | 1355 TypeofState typeof_state, |
| 1356 Label* slow) { | 1356 Label* slow) { |
| 1357 Register current = cp; | 1357 Register current = cp; |
| 1358 Register next = x10; | 1358 Register next = x10; |
| 1359 Register temp = x11; | 1359 Register temp = x11; |
| 1360 | 1360 |
| 1361 Scope* s = scope(); | 1361 Scope* s = scope(); |
| 1362 while (s != NULL) { | 1362 while (s != NULL) { |
| 1363 if (s->num_heap_slots() > 0) { | 1363 if (s->num_heap_slots() > 0) { |
| 1364 if (s->calls_sloppy_eval()) { | 1364 if (s->calls_sloppy_eval()) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1388 // Check that extension is NULL. | 1388 // Check that extension is NULL. |
| 1389 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); | 1389 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); |
| 1390 __ Cbnz(temp, slow); | 1390 __ Cbnz(temp, slow); |
| 1391 // Load next context in chain. | 1391 // Load next context in chain. |
| 1392 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); | 1392 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); |
| 1393 __ B(&loop); | 1393 __ B(&loop); |
| 1394 __ Bind(&fast); | 1394 __ Bind(&fast); |
| 1395 } | 1395 } |
| 1396 | 1396 |
| 1397 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); | 1397 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); |
| 1398 __ Mov(LoadIC::NameRegister(), Operand(var->name())); | 1398 __ Mov(LoadIC::NameRegister(), Operand(proxy->var()->name())); |
| 1399 if (FLAG_vector_ics) { |
| 1400 __ Mov(LoadIC::SlotRegister(), |
| 1401 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 1402 } |
| 1403 |
| 1399 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL | 1404 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL |
| 1400 : CONTEXTUAL; | 1405 : CONTEXTUAL; |
| 1401 CallLoadIC(mode); | 1406 CallLoadIC(mode); |
| 1402 } | 1407 } |
| 1403 | 1408 |
| 1404 | 1409 |
| 1405 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1410 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1406 Label* slow) { | 1411 Label* slow) { |
| 1407 ASSERT(var->IsContextSlot()); | 1412 ASSERT(var->IsContextSlot()); |
| 1408 Register context = cp; | 1413 Register context = cp; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1425 __ Ldr(temp, ContextMemOperand(context, Context::EXTENSION_INDEX)); | 1430 __ Ldr(temp, ContextMemOperand(context, Context::EXTENSION_INDEX)); |
| 1426 __ Cbnz(temp, slow); | 1431 __ Cbnz(temp, slow); |
| 1427 | 1432 |
| 1428 // This function is used only for loads, not stores, so it's safe to | 1433 // This function is used only for loads, not stores, so it's safe to |
| 1429 // return an cp-based operand (the write barrier cannot be allowed to | 1434 // return an cp-based operand (the write barrier cannot be allowed to |
| 1430 // destroy the cp register). | 1435 // destroy the cp register). |
| 1431 return ContextMemOperand(context, var->index()); | 1436 return ContextMemOperand(context, var->index()); |
| 1432 } | 1437 } |
| 1433 | 1438 |
| 1434 | 1439 |
| 1435 void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var, | 1440 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, |
| 1436 TypeofState typeof_state, | 1441 TypeofState typeof_state, |
| 1437 Label* slow, | 1442 Label* slow, |
| 1438 Label* done) { | 1443 Label* done) { |
| 1439 // Generate fast-case code for variables that might be shadowed by | 1444 // Generate fast-case code for variables that might be shadowed by |
| 1440 // eval-introduced variables. Eval is used a lot without | 1445 // eval-introduced variables. Eval is used a lot without |
| 1441 // introducing variables. In those cases, we do not want to | 1446 // introducing variables. In those cases, we do not want to |
| 1442 // perform a runtime call for all variables in the scope | 1447 // perform a runtime call for all variables in the scope |
| 1443 // containing the eval. | 1448 // containing the eval. |
| 1449 Variable* var = proxy->var(); |
| 1444 if (var->mode() == DYNAMIC_GLOBAL) { | 1450 if (var->mode() == DYNAMIC_GLOBAL) { |
| 1445 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); | 1451 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); |
| 1446 __ B(done); | 1452 __ B(done); |
| 1447 } else if (var->mode() == DYNAMIC_LOCAL) { | 1453 } else if (var->mode() == DYNAMIC_LOCAL) { |
| 1448 Variable* local = var->local_if_not_shadowed(); | 1454 Variable* local = var->local_if_not_shadowed(); |
| 1449 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow)); | 1455 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow)); |
| 1450 if (local->mode() == LET || local->mode() == CONST || | 1456 if (local->mode() == LET || local->mode() == CONST || |
| 1451 local->mode() == CONST_LEGACY) { | 1457 local->mode() == CONST_LEGACY) { |
| 1452 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done); | 1458 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done); |
| 1453 if (local->mode() == CONST_LEGACY) { | 1459 if (local->mode() == CONST_LEGACY) { |
| 1454 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | 1460 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |
| 1455 } else { // LET || CONST | 1461 } else { // LET || CONST |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1468 SetSourcePosition(proxy->position()); | 1474 SetSourcePosition(proxy->position()); |
| 1469 Variable* var = proxy->var(); | 1475 Variable* var = proxy->var(); |
| 1470 | 1476 |
| 1471 // Three cases: global variables, lookup variables, and all other types of | 1477 // Three cases: global variables, lookup variables, and all other types of |
| 1472 // variables. | 1478 // variables. |
| 1473 switch (var->location()) { | 1479 switch (var->location()) { |
| 1474 case Variable::UNALLOCATED: { | 1480 case Variable::UNALLOCATED: { |
| 1475 Comment cmnt(masm_, "Global variable"); | 1481 Comment cmnt(masm_, "Global variable"); |
| 1476 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); | 1482 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); |
| 1477 __ Mov(LoadIC::NameRegister(), Operand(var->name())); | 1483 __ Mov(LoadIC::NameRegister(), Operand(var->name())); |
| 1484 if (FLAG_vector_ics) { |
| 1485 __ Mov(LoadIC::SlotRegister(), |
| 1486 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 1487 } |
| 1478 CallLoadIC(CONTEXTUAL); | 1488 CallLoadIC(CONTEXTUAL); |
| 1479 context()->Plug(x0); | 1489 context()->Plug(x0); |
| 1480 break; | 1490 break; |
| 1481 } | 1491 } |
| 1482 | 1492 |
| 1483 case Variable::PARAMETER: | 1493 case Variable::PARAMETER: |
| 1484 case Variable::LOCAL: | 1494 case Variable::LOCAL: |
| 1485 case Variable::CONTEXT: { | 1495 case Variable::CONTEXT: { |
| 1486 Comment cmnt(masm_, var->IsContextSlot() | 1496 Comment cmnt(masm_, var->IsContextSlot() |
| 1487 ? "Context variable" | 1497 ? "Context variable" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 } | 1554 } |
| 1545 } | 1555 } |
| 1546 context()->Plug(var); | 1556 context()->Plug(var); |
| 1547 break; | 1557 break; |
| 1548 } | 1558 } |
| 1549 | 1559 |
| 1550 case Variable::LOOKUP: { | 1560 case Variable::LOOKUP: { |
| 1551 Label done, slow; | 1561 Label done, slow; |
| 1552 // Generate code for loading from variables potentially shadowed by | 1562 // Generate code for loading from variables potentially shadowed by |
| 1553 // eval-introduced variables. | 1563 // eval-introduced variables. |
| 1554 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); | 1564 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1555 __ Bind(&slow); | 1565 __ Bind(&slow); |
| 1556 Comment cmnt(masm_, "Lookup variable"); | 1566 Comment cmnt(masm_, "Lookup variable"); |
| 1557 __ Mov(x1, Operand(var->name())); | 1567 __ Mov(x1, Operand(var->name())); |
| 1558 __ Push(cp, x1); // Context and name. | 1568 __ Push(cp, x1); // Context and name. |
| 1559 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 1569 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 1560 __ Bind(&done); | 1570 __ Bind(&done); |
| 1561 context()->Plug(x0); | 1571 context()->Plug(x0); |
| 1562 break; | 1572 break; |
| 1563 } | 1573 } |
| 1564 } | 1574 } |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1943 EmitKeyedPropertyAssignment(expr); | 1953 EmitKeyedPropertyAssignment(expr); |
| 1944 break; | 1954 break; |
| 1945 } | 1955 } |
| 1946 } | 1956 } |
| 1947 | 1957 |
| 1948 | 1958 |
| 1949 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1959 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1950 SetSourcePosition(prop->position()); | 1960 SetSourcePosition(prop->position()); |
| 1951 Literal* key = prop->key()->AsLiteral(); | 1961 Literal* key = prop->key()->AsLiteral(); |
| 1952 __ Mov(LoadIC::NameRegister(), Operand(key->value())); | 1962 __ Mov(LoadIC::NameRegister(), Operand(key->value())); |
| 1953 // Call load IC. It has arguments receiver and property name x0 and x2. | 1963 if (FLAG_vector_ics) { |
| 1954 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 1964 __ Mov(LoadIC::SlotRegister(), |
| 1965 Smi::FromInt(prop->PropertyFeedbackSlot())); |
| 1966 CallLoadIC(NOT_CONTEXTUAL); |
| 1967 } else { |
| 1968 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 1969 } |
| 1955 } | 1970 } |
| 1956 | 1971 |
| 1957 | 1972 |
| 1958 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1973 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1959 SetSourcePosition(prop->position()); | 1974 SetSourcePosition(prop->position()); |
| 1960 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1975 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1961 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1976 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1962 CallIC(ic, prop->PropertyFeedbackId()); | 1977 if (FLAG_vector_ics) { |
| 1978 __ Mov(LoadIC::SlotRegister(), |
| 1979 Smi::FromInt(prop->PropertyFeedbackSlot())); |
| 1980 CallIC(ic); |
| 1981 } else { |
| 1982 CallIC(ic, prop->PropertyFeedbackId()); |
| 1983 } |
| 1963 } | 1984 } |
| 1964 | 1985 |
| 1965 | 1986 |
| 1966 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1987 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 1967 Token::Value op, | 1988 Token::Value op, |
| 1968 OverwriteMode mode, | 1989 OverwriteMode mode, |
| 1969 Expression* left_expr, | 1990 Expression* left_expr, |
| 1970 Expression* right_expr) { | 1991 Expression* right_expr) { |
| 1971 Label done, both_smis, stub_call; | 1992 Label done, both_smis, stub_call; |
| 1972 | 1993 |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2445 EmitCallWithLoadIC(expr); | 2466 EmitCallWithLoadIC(expr); |
| 2446 | 2467 |
| 2447 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2468 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
| 2448 // Call to a lookup slot (dynamically introduced variable). | 2469 // Call to a lookup slot (dynamically introduced variable). |
| 2449 VariableProxy* proxy = callee->AsVariableProxy(); | 2470 VariableProxy* proxy = callee->AsVariableProxy(); |
| 2450 Label slow, done; | 2471 Label slow, done; |
| 2451 | 2472 |
| 2452 { PreservePositionScope scope(masm()->positions_recorder()); | 2473 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2453 // Generate code for loading from variables potentially shadowed | 2474 // Generate code for loading from variables potentially shadowed |
| 2454 // by eval-introduced variables. | 2475 // by eval-introduced variables. |
| 2455 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2476 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
| 2456 } | 2477 } |
| 2457 | 2478 |
| 2458 __ Bind(&slow); | 2479 __ Bind(&slow); |
| 2459 // Call the runtime to find the function to call (returned in x0) | 2480 // Call the runtime to find the function to call (returned in x0) |
| 2460 // and the object holding it (returned in x1). | 2481 // and the object holding it (returned in x1). |
| 2461 __ Mov(x10, Operand(proxy->name())); | 2482 __ Mov(x10, Operand(proxy->name())); |
| 2462 __ Push(context_register(), x10); | 2483 __ Push(context_register(), x10); |
| 2463 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 2484 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 2464 __ Push(x0, x1); // Receiver, function. | 2485 __ Push(x0, x1); // Receiver, function. |
| 2465 | 2486 |
| (...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3738 if (expr->is_jsruntime()) { | 3759 if (expr->is_jsruntime()) { |
| 3739 // Push the builtins object as the receiver. | 3760 // Push the builtins object as the receiver. |
| 3740 __ Ldr(x10, GlobalObjectMemOperand()); | 3761 __ Ldr(x10, GlobalObjectMemOperand()); |
| 3741 __ Ldr(LoadIC::ReceiverRegister(), | 3762 __ Ldr(LoadIC::ReceiverRegister(), |
| 3742 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); | 3763 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); |
| 3743 __ Push(LoadIC::ReceiverRegister()); | 3764 __ Push(LoadIC::ReceiverRegister()); |
| 3744 | 3765 |
| 3745 // Load the function from the receiver. | 3766 // Load the function from the receiver. |
| 3746 Handle<String> name = expr->name(); | 3767 Handle<String> name = expr->name(); |
| 3747 __ Mov(LoadIC::NameRegister(), Operand(name)); | 3768 __ Mov(LoadIC::NameRegister(), Operand(name)); |
| 3748 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 3769 if (FLAG_vector_ics) { |
| 3770 __ Mov(LoadIC::SlotRegister(), |
| 3771 Smi::FromInt(expr->CallRuntimeFeedbackSlot())); |
| 3772 CallLoadIC(NOT_CONTEXTUAL); |
| 3773 } else { |
| 3774 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 3775 } |
| 3749 | 3776 |
| 3750 // Push the target function under the receiver. | 3777 // Push the target function under the receiver. |
| 3751 __ Pop(x10); | 3778 __ Pop(x10); |
| 3752 __ Push(x0, x10); | 3779 __ Push(x0, x10); |
| 3753 | 3780 |
| 3754 int arg_count = args->length(); | 3781 int arg_count = args->length(); |
| 3755 for (int i = 0; i < arg_count; i++) { | 3782 for (int i = 0; i < arg_count; i++) { |
| 3756 VisitForStackValue(args->at(i)); | 3783 VisitForStackValue(args->at(i)); |
| 3757 } | 3784 } |
| 3758 | 3785 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4073 | 4100 |
| 4074 | 4101 |
| 4075 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4102 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4076 ASSERT(!context()->IsEffect()); | 4103 ASSERT(!context()->IsEffect()); |
| 4077 ASSERT(!context()->IsTest()); | 4104 ASSERT(!context()->IsTest()); |
| 4078 VariableProxy* proxy = expr->AsVariableProxy(); | 4105 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4079 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4106 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4080 Comment cmnt(masm_, "Global variable"); | 4107 Comment cmnt(masm_, "Global variable"); |
| 4081 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); | 4108 __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); |
| 4082 __ Mov(LoadIC::NameRegister(), Operand(proxy->name())); | 4109 __ Mov(LoadIC::NameRegister(), Operand(proxy->name())); |
| 4110 if (FLAG_vector_ics) { |
| 4111 __ Mov(LoadIC::SlotRegister(), |
| 4112 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 4113 } |
| 4083 // Use a regular load, not a contextual load, to avoid a reference | 4114 // Use a regular load, not a contextual load, to avoid a reference |
| 4084 // error. | 4115 // error. |
| 4085 CallLoadIC(NOT_CONTEXTUAL); | 4116 CallLoadIC(NOT_CONTEXTUAL); |
| 4086 PrepareForBailout(expr, TOS_REG); | 4117 PrepareForBailout(expr, TOS_REG); |
| 4087 context()->Plug(x0); | 4118 context()->Plug(x0); |
| 4088 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4119 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4089 Label done, slow; | 4120 Label done, slow; |
| 4090 | 4121 |
| 4091 // Generate code for loading from variables potentially shadowed | 4122 // Generate code for loading from variables potentially shadowed |
| 4092 // by eval-introduced variables. | 4123 // by eval-introduced variables. |
| 4093 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4124 EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done); |
| 4094 | 4125 |
| 4095 __ Bind(&slow); | 4126 __ Bind(&slow); |
| 4096 __ Mov(x0, Operand(proxy->name())); | 4127 __ Mov(x0, Operand(proxy->name())); |
| 4097 __ Push(cp, x0); | 4128 __ Push(cp, x0); |
| 4098 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); | 4129 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); |
| 4099 PrepareForBailout(expr, TOS_REG); | 4130 PrepareForBailout(expr, TOS_REG); |
| 4100 __ Bind(&done); | 4131 __ Bind(&done); |
| 4101 | 4132 |
| 4102 context()->Plug(x0); | 4133 context()->Plug(x0); |
| 4103 } else { | 4134 } else { |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4425 __ Bind(&l_next); | 4456 __ Bind(&l_next); |
| 4426 | 4457 |
| 4427 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" | 4458 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" |
| 4428 __ Peek(x3, 1 * kPointerSize); // iter | 4459 __ Peek(x3, 1 * kPointerSize); // iter |
| 4429 __ Push(load_name, x3, x0); // "next", iter, received | 4460 __ Push(load_name, x3, x0); // "next", iter, received |
| 4430 | 4461 |
| 4431 // result = receiver[f](arg); | 4462 // result = receiver[f](arg); |
| 4432 __ Bind(&l_call); | 4463 __ Bind(&l_call); |
| 4433 __ Peek(load_receiver, 1 * kPointerSize); | 4464 __ Peek(load_receiver, 1 * kPointerSize); |
| 4434 __ Peek(load_name, 2 * kPointerSize); | 4465 __ Peek(load_name, 2 * kPointerSize); |
| 4466 if (FLAG_vector_ics) { |
| 4467 __ Mov(LoadIC::SlotRegister(), |
| 4468 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); |
| 4469 } |
| 4435 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 4470 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 4436 CallIC(ic, TypeFeedbackId::None()); | 4471 CallIC(ic, TypeFeedbackId::None()); |
| 4437 __ Mov(x1, x0); | 4472 __ Mov(x1, x0); |
| 4438 __ Poke(x1, 2 * kPointerSize); | 4473 __ Poke(x1, 2 * kPointerSize); |
| 4439 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 4474 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 4440 __ CallStub(&stub); | 4475 __ CallStub(&stub); |
| 4441 | 4476 |
| 4442 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4477 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4443 __ Drop(1); // The function is still on the stack; drop it. | 4478 __ Drop(1); // The function is still on the stack; drop it. |
| 4444 | 4479 |
| 4445 // if (!result.done) goto l_try; | 4480 // if (!result.done) goto l_try; |
| 4446 __ Bind(&l_loop); | 4481 __ Bind(&l_loop); |
| 4447 __ Move(load_receiver, x0); | 4482 __ Move(load_receiver, x0); |
| 4448 | 4483 |
| 4449 __ Push(load_receiver); // save result | 4484 __ Push(load_receiver); // save result |
| 4450 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 4485 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
| 4486 if (FLAG_vector_ics) { |
| 4487 __ Mov(LoadIC::SlotRegister(), |
| 4488 Smi::FromInt(expr->DoneFeedbackSlot())); |
| 4489 } |
| 4451 CallLoadIC(NOT_CONTEXTUAL); // x0=result.done | 4490 CallLoadIC(NOT_CONTEXTUAL); // x0=result.done |
| 4452 // The ToBooleanStub argument (result.done) is in x0. | 4491 // The ToBooleanStub argument (result.done) is in x0. |
| 4453 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 4492 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 4454 CallIC(bool_ic); | 4493 CallIC(bool_ic); |
| 4455 __ Cbz(x0, &l_try); | 4494 __ Cbz(x0, &l_try); |
| 4456 | 4495 |
| 4457 // result.value | 4496 // result.value |
| 4458 __ Pop(load_receiver); // result | 4497 __ Pop(load_receiver); // result |
| 4459 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" | 4498 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
| 4499 if (FLAG_vector_ics) { |
| 4500 __ Mov(LoadIC::SlotRegister(), |
| 4501 Smi::FromInt(expr->ValueFeedbackSlot())); |
| 4502 } |
| 4460 CallLoadIC(NOT_CONTEXTUAL); // x0=result.value | 4503 CallLoadIC(NOT_CONTEXTUAL); // x0=result.value |
| 4461 context()->DropAndPlug(2, x0); // drop iter and g | 4504 context()->DropAndPlug(2, x0); // drop iter and g |
| 4462 break; | 4505 break; |
| 4463 } | 4506 } |
| 4464 } | 4507 } |
| 4465 } | 4508 } |
| 4466 | 4509 |
| 4467 | 4510 |
| 4468 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 4511 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 4469 Expression *value, | 4512 Expression *value, |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4879 return previous_; | 4922 return previous_; |
| 4880 } | 4923 } |
| 4881 | 4924 |
| 4882 | 4925 |
| 4883 #undef __ | 4926 #undef __ |
| 4884 | 4927 |
| 4885 | 4928 |
| 4886 } } // namespace v8::internal | 4929 } } // namespace v8::internal |
| 4887 | 4930 |
| 4888 #endif // V8_TARGET_ARCH_ARM64 | 4931 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |