| 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 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 __ JumpIfRoot(temp, Heap::kNativeContextMapRootIndex, &fast); | 1376 __ JumpIfRoot(temp, Heap::kNativeContextMapRootIndex, &fast); |
| 1377 // Check that extension is NULL. | 1377 // Check that extension is NULL. |
| 1378 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); | 1378 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); |
| 1379 __ Cbnz(temp, slow); | 1379 __ Cbnz(temp, slow); |
| 1380 // Load next context in chain. | 1380 // Load next context in chain. |
| 1381 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); | 1381 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); |
| 1382 __ B(&loop); | 1382 __ B(&loop); |
| 1383 __ Bind(&fast); | 1383 __ Bind(&fast); |
| 1384 } | 1384 } |
| 1385 | 1385 |
| 1386 __ Ldr(LoadConvention::ReceiverRegister(), GlobalObjectMemOperand()); | 1386 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
| 1387 __ Mov(LoadConvention::NameRegister(), Operand(proxy->var()->name())); | 1387 __ Mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name())); |
| 1388 if (FLAG_vector_ics) { | 1388 if (FLAG_vector_ics) { |
| 1389 __ Mov(VectorLoadConvention::SlotRegister(), | 1389 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 1390 Smi::FromInt(proxy->VariableFeedbackSlot())); | 1390 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 1391 } | 1391 } |
| 1392 | 1392 |
| 1393 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL | 1393 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL |
| 1394 : CONTEXTUAL; | 1394 : CONTEXTUAL; |
| 1395 CallLoadIC(mode); | 1395 CallLoadIC(mode); |
| 1396 } | 1396 } |
| 1397 | 1397 |
| 1398 | 1398 |
| 1399 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1399 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1461 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1462 // Record position before possible IC call. | 1462 // Record position before possible IC call. |
| 1463 SetSourcePosition(proxy->position()); | 1463 SetSourcePosition(proxy->position()); |
| 1464 Variable* var = proxy->var(); | 1464 Variable* var = proxy->var(); |
| 1465 | 1465 |
| 1466 // Three cases: global variables, lookup variables, and all other types of | 1466 // Three cases: global variables, lookup variables, and all other types of |
| 1467 // variables. | 1467 // variables. |
| 1468 switch (var->location()) { | 1468 switch (var->location()) { |
| 1469 case Variable::UNALLOCATED: { | 1469 case Variable::UNALLOCATED: { |
| 1470 Comment cmnt(masm_, "Global variable"); | 1470 Comment cmnt(masm_, "Global variable"); |
| 1471 __ Ldr(LoadConvention::ReceiverRegister(), GlobalObjectMemOperand()); | 1471 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
| 1472 __ Mov(LoadConvention::NameRegister(), Operand(var->name())); | 1472 __ Mov(LoadDescriptor::NameRegister(), Operand(var->name())); |
| 1473 if (FLAG_vector_ics) { | 1473 if (FLAG_vector_ics) { |
| 1474 __ Mov(VectorLoadConvention::SlotRegister(), | 1474 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 1475 Smi::FromInt(proxy->VariableFeedbackSlot())); | 1475 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 1476 } | 1476 } |
| 1477 CallLoadIC(CONTEXTUAL); | 1477 CallLoadIC(CONTEXTUAL); |
| 1478 context()->Plug(x0); | 1478 context()->Plug(x0); |
| 1479 break; | 1479 break; |
| 1480 } | 1480 } |
| 1481 | 1481 |
| 1482 case Variable::PARAMETER: | 1482 case Variable::PARAMETER: |
| 1483 case Variable::LOCAL: | 1483 case Variable::LOCAL: |
| 1484 case Variable::CONTEXT: { | 1484 case Variable::CONTEXT: { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1674 switch (property->kind()) { | 1674 switch (property->kind()) { |
| 1675 case ObjectLiteral::Property::CONSTANT: | 1675 case ObjectLiteral::Property::CONSTANT: |
| 1676 UNREACHABLE(); | 1676 UNREACHABLE(); |
| 1677 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1677 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1678 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1678 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1679 // Fall through. | 1679 // Fall through. |
| 1680 case ObjectLiteral::Property::COMPUTED: | 1680 case ObjectLiteral::Property::COMPUTED: |
| 1681 if (key->value()->IsInternalizedString()) { | 1681 if (key->value()->IsInternalizedString()) { |
| 1682 if (property->emit_store()) { | 1682 if (property->emit_store()) { |
| 1683 VisitForAccumulatorValue(value); | 1683 VisitForAccumulatorValue(value); |
| 1684 DCHECK(StoreConvention::ValueRegister().is(x0)); | 1684 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
| 1685 __ Mov(StoreConvention::NameRegister(), Operand(key->value())); | 1685 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value())); |
| 1686 __ Peek(StoreConvention::ReceiverRegister(), 0); | 1686 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1687 CallStoreIC(key->LiteralFeedbackId()); | 1687 CallStoreIC(key->LiteralFeedbackId()); |
| 1688 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1688 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1689 } else { | 1689 } else { |
| 1690 VisitForEffect(value); | 1690 VisitForEffect(value); |
| 1691 } | 1691 } |
| 1692 break; | 1692 break; |
| 1693 } | 1693 } |
| 1694 if (property->emit_store()) { | 1694 if (property->emit_store()) { |
| 1695 // Duplicate receiver on stack. | 1695 // Duplicate receiver on stack. |
| 1696 __ Peek(x0, 0); | 1696 __ Peek(x0, 0); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 | 1854 |
| 1855 // Evaluate LHS expression. | 1855 // Evaluate LHS expression. |
| 1856 switch (assign_type) { | 1856 switch (assign_type) { |
| 1857 case VARIABLE: | 1857 case VARIABLE: |
| 1858 // Nothing to do here. | 1858 // Nothing to do here. |
| 1859 break; | 1859 break; |
| 1860 case NAMED_PROPERTY: | 1860 case NAMED_PROPERTY: |
| 1861 if (expr->is_compound()) { | 1861 if (expr->is_compound()) { |
| 1862 // We need the receiver both on the stack and in the register. | 1862 // We need the receiver both on the stack and in the register. |
| 1863 VisitForStackValue(property->obj()); | 1863 VisitForStackValue(property->obj()); |
| 1864 __ Peek(LoadConvention::ReceiverRegister(), 0); | 1864 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 1865 } else { | 1865 } else { |
| 1866 VisitForStackValue(property->obj()); | 1866 VisitForStackValue(property->obj()); |
| 1867 } | 1867 } |
| 1868 break; | 1868 break; |
| 1869 case KEYED_PROPERTY: | 1869 case KEYED_PROPERTY: |
| 1870 if (expr->is_compound()) { | 1870 if (expr->is_compound()) { |
| 1871 VisitForStackValue(property->obj()); | 1871 VisitForStackValue(property->obj()); |
| 1872 VisitForStackValue(property->key()); | 1872 VisitForStackValue(property->key()); |
| 1873 __ Peek(LoadConvention::ReceiverRegister(), 1 * kPointerSize); | 1873 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
| 1874 __ Peek(LoadConvention::NameRegister(), 0); | 1874 __ Peek(LoadDescriptor::NameRegister(), 0); |
| 1875 } else { | 1875 } else { |
| 1876 VisitForStackValue(property->obj()); | 1876 VisitForStackValue(property->obj()); |
| 1877 VisitForStackValue(property->key()); | 1877 VisitForStackValue(property->key()); |
| 1878 } | 1878 } |
| 1879 break; | 1879 break; |
| 1880 } | 1880 } |
| 1881 | 1881 |
| 1882 // For compound assignments we need another deoptimization point after the | 1882 // For compound assignments we need another deoptimization point after the |
| 1883 // variable/property load. | 1883 // variable/property load. |
| 1884 if (expr->is_compound()) { | 1884 if (expr->is_compound()) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1941 case KEYED_PROPERTY: | 1941 case KEYED_PROPERTY: |
| 1942 EmitKeyedPropertyAssignment(expr); | 1942 EmitKeyedPropertyAssignment(expr); |
| 1943 break; | 1943 break; |
| 1944 } | 1944 } |
| 1945 } | 1945 } |
| 1946 | 1946 |
| 1947 | 1947 |
| 1948 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1948 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1949 SetSourcePosition(prop->position()); | 1949 SetSourcePosition(prop->position()); |
| 1950 Literal* key = prop->key()->AsLiteral(); | 1950 Literal* key = prop->key()->AsLiteral(); |
| 1951 __ Mov(LoadConvention::NameRegister(), Operand(key->value())); | 1951 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); |
| 1952 if (FLAG_vector_ics) { | 1952 if (FLAG_vector_ics) { |
| 1953 __ Mov(VectorLoadConvention::SlotRegister(), | 1953 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 1954 Smi::FromInt(prop->PropertyFeedbackSlot())); | 1954 Smi::FromInt(prop->PropertyFeedbackSlot())); |
| 1955 CallLoadIC(NOT_CONTEXTUAL); | 1955 CallLoadIC(NOT_CONTEXTUAL); |
| 1956 } else { | 1956 } else { |
| 1957 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 1957 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 1958 } | 1958 } |
| 1959 } | 1959 } |
| 1960 | 1960 |
| 1961 | 1961 |
| 1962 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1962 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1963 SetSourcePosition(prop->position()); | 1963 SetSourcePosition(prop->position()); |
| 1964 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1964 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1965 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1965 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1966 if (FLAG_vector_ics) { | 1966 if (FLAG_vector_ics) { |
| 1967 __ Mov(VectorLoadConvention::SlotRegister(), | 1967 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 1968 Smi::FromInt(prop->PropertyFeedbackSlot())); | 1968 Smi::FromInt(prop->PropertyFeedbackSlot())); |
| 1969 CallIC(ic); | 1969 CallIC(ic); |
| 1970 } else { | 1970 } else { |
| 1971 CallIC(ic, prop->PropertyFeedbackId()); | 1971 CallIC(ic, prop->PropertyFeedbackId()); |
| 1972 } | 1972 } |
| 1973 } | 1973 } |
| 1974 | 1974 |
| 1975 | 1975 |
| 1976 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1976 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 1977 Token::Value op, | 1977 Token::Value op, |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2106 Variable* var = expr->AsVariableProxy()->var(); | 2106 Variable* var = expr->AsVariableProxy()->var(); |
| 2107 EffectContext context(this); | 2107 EffectContext context(this); |
| 2108 EmitVariableAssignment(var, Token::ASSIGN); | 2108 EmitVariableAssignment(var, Token::ASSIGN); |
| 2109 break; | 2109 break; |
| 2110 } | 2110 } |
| 2111 case NAMED_PROPERTY: { | 2111 case NAMED_PROPERTY: { |
| 2112 __ Push(x0); // Preserve value. | 2112 __ Push(x0); // Preserve value. |
| 2113 VisitForAccumulatorValue(prop->obj()); | 2113 VisitForAccumulatorValue(prop->obj()); |
| 2114 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid | 2114 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid |
| 2115 // this copy. | 2115 // this copy. |
| 2116 __ Mov(StoreConvention::ReceiverRegister(), x0); | 2116 __ Mov(StoreDescriptor::ReceiverRegister(), x0); |
| 2117 __ Pop(StoreConvention::ValueRegister()); // Restore value. | 2117 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2118 __ Mov(StoreConvention::NameRegister(), | 2118 __ Mov(StoreDescriptor::NameRegister(), |
| 2119 Operand(prop->key()->AsLiteral()->value())); | 2119 Operand(prop->key()->AsLiteral()->value())); |
| 2120 CallStoreIC(); | 2120 CallStoreIC(); |
| 2121 break; | 2121 break; |
| 2122 } | 2122 } |
| 2123 case KEYED_PROPERTY: { | 2123 case KEYED_PROPERTY: { |
| 2124 __ Push(x0); // Preserve value. | 2124 __ Push(x0); // Preserve value. |
| 2125 VisitForStackValue(prop->obj()); | 2125 VisitForStackValue(prop->obj()); |
| 2126 VisitForAccumulatorValue(prop->key()); | 2126 VisitForAccumulatorValue(prop->key()); |
| 2127 __ Mov(StoreConvention::NameRegister(), x0); | 2127 __ Mov(StoreDescriptor::NameRegister(), x0); |
| 2128 __ Pop(StoreConvention::ReceiverRegister(), | 2128 __ Pop(StoreDescriptor::ReceiverRegister(), |
| 2129 StoreConvention::ValueRegister()); | 2129 StoreDescriptor::ValueRegister()); |
| 2130 Handle<Code> ic = strict_mode() == SLOPPY | 2130 Handle<Code> ic = strict_mode() == SLOPPY |
| 2131 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2131 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2132 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2132 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2133 CallIC(ic); | 2133 CallIC(ic); |
| 2134 break; | 2134 break; |
| 2135 } | 2135 } |
| 2136 } | 2136 } |
| 2137 context()->Plug(x0); | 2137 context()->Plug(x0); |
| 2138 } | 2138 } |
| 2139 | 2139 |
| 2140 | 2140 |
| 2141 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2141 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2142 Variable* var, MemOperand location) { | 2142 Variable* var, MemOperand location) { |
| 2143 __ Str(result_register(), location); | 2143 __ Str(result_register(), location); |
| 2144 if (var->IsContextSlot()) { | 2144 if (var->IsContextSlot()) { |
| 2145 // RecordWrite may destroy all its register arguments. | 2145 // RecordWrite may destroy all its register arguments. |
| 2146 __ Mov(x10, result_register()); | 2146 __ Mov(x10, result_register()); |
| 2147 int offset = Context::SlotOffset(var->index()); | 2147 int offset = Context::SlotOffset(var->index()); |
| 2148 __ RecordWriteContextSlot( | 2148 __ RecordWriteContextSlot( |
| 2149 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); | 2149 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2150 } | 2150 } |
| 2151 } | 2151 } |
| 2152 | 2152 |
| 2153 | 2153 |
| 2154 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2154 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 2155 Token::Value op) { | 2155 Token::Value op) { |
| 2156 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 2156 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); |
| 2157 if (var->IsUnallocated()) { | 2157 if (var->IsUnallocated()) { |
| 2158 // Global var, const, or let. | 2158 // Global var, const, or let. |
| 2159 __ Mov(StoreConvention::NameRegister(), Operand(var->name())); | 2159 __ Mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
| 2160 __ Ldr(StoreConvention::ReceiverRegister(), GlobalObjectMemOperand()); | 2160 __ Ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
| 2161 CallStoreIC(); | 2161 CallStoreIC(); |
| 2162 | 2162 |
| 2163 } else if (op == Token::INIT_CONST_LEGACY) { | 2163 } else if (op == Token::INIT_CONST_LEGACY) { |
| 2164 // Const initializers need a write barrier. | 2164 // Const initializers need a write barrier. |
| 2165 DCHECK(!var->IsParameter()); // No const parameters. | 2165 DCHECK(!var->IsParameter()); // No const parameters. |
| 2166 if (var->IsLookupSlot()) { | 2166 if (var->IsLookupSlot()) { |
| 2167 __ Mov(x1, Operand(var->name())); | 2167 __ Mov(x1, Operand(var->name())); |
| 2168 __ Push(x0, cp, x1); | 2168 __ Push(x0, cp, x1); |
| 2169 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); | 2169 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
| 2170 } else { | 2170 } else { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2222 | 2222 |
| 2223 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2223 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2224 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 2224 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); |
| 2225 // Assignment to a property, using a named store IC. | 2225 // Assignment to a property, using a named store IC. |
| 2226 Property* prop = expr->target()->AsProperty(); | 2226 Property* prop = expr->target()->AsProperty(); |
| 2227 DCHECK(prop != NULL); | 2227 DCHECK(prop != NULL); |
| 2228 DCHECK(prop->key()->IsLiteral()); | 2228 DCHECK(prop->key()->IsLiteral()); |
| 2229 | 2229 |
| 2230 // Record source code position before IC call. | 2230 // Record source code position before IC call. |
| 2231 SetSourcePosition(expr->position()); | 2231 SetSourcePosition(expr->position()); |
| 2232 __ Mov(StoreConvention::NameRegister(), | 2232 __ Mov(StoreDescriptor::NameRegister(), |
| 2233 Operand(prop->key()->AsLiteral()->value())); | 2233 Operand(prop->key()->AsLiteral()->value())); |
| 2234 __ Pop(StoreConvention::ReceiverRegister()); | 2234 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2235 CallStoreIC(expr->AssignmentFeedbackId()); | 2235 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2236 | 2236 |
| 2237 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2237 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2238 context()->Plug(x0); | 2238 context()->Plug(x0); |
| 2239 } | 2239 } |
| 2240 | 2240 |
| 2241 | 2241 |
| 2242 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2242 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2243 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 2243 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
| 2244 // Assignment to a property, using a keyed store IC. | 2244 // Assignment to a property, using a keyed store IC. |
| 2245 | 2245 |
| 2246 // Record source code position before IC call. | 2246 // Record source code position before IC call. |
| 2247 SetSourcePosition(expr->position()); | 2247 SetSourcePosition(expr->position()); |
| 2248 // TODO(all): Could we pass this in registers rather than on the stack? | 2248 // TODO(all): Could we pass this in registers rather than on the stack? |
| 2249 __ Pop(StoreConvention::NameRegister(), StoreConvention::ReceiverRegister()); | 2249 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); |
| 2250 DCHECK(StoreConvention::ValueRegister().is(x0)); | 2250 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
| 2251 | 2251 |
| 2252 Handle<Code> ic = strict_mode() == SLOPPY | 2252 Handle<Code> ic = strict_mode() == SLOPPY |
| 2253 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2253 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2254 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2254 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2255 CallIC(ic, expr->AssignmentFeedbackId()); | 2255 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2256 | 2256 |
| 2257 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2257 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2258 context()->Plug(x0); | 2258 context()->Plug(x0); |
| 2259 } | 2259 } |
| 2260 | 2260 |
| 2261 | 2261 |
| 2262 void FullCodeGenerator::VisitProperty(Property* expr) { | 2262 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2263 Comment cmnt(masm_, "[ Property"); | 2263 Comment cmnt(masm_, "[ Property"); |
| 2264 Expression* key = expr->key(); | 2264 Expression* key = expr->key(); |
| 2265 | 2265 |
| 2266 if (key->IsPropertyName()) { | 2266 if (key->IsPropertyName()) { |
| 2267 VisitForAccumulatorValue(expr->obj()); | 2267 VisitForAccumulatorValue(expr->obj()); |
| 2268 __ Move(LoadConvention::ReceiverRegister(), x0); | 2268 __ Move(LoadDescriptor::ReceiverRegister(), x0); |
| 2269 EmitNamedPropertyLoad(expr); | 2269 EmitNamedPropertyLoad(expr); |
| 2270 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2270 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2271 context()->Plug(x0); | 2271 context()->Plug(x0); |
| 2272 } else { | 2272 } else { |
| 2273 VisitForStackValue(expr->obj()); | 2273 VisitForStackValue(expr->obj()); |
| 2274 VisitForAccumulatorValue(expr->key()); | 2274 VisitForAccumulatorValue(expr->key()); |
| 2275 __ Move(LoadConvention::NameRegister(), x0); | 2275 __ Move(LoadDescriptor::NameRegister(), x0); |
| 2276 __ Pop(LoadConvention::ReceiverRegister()); | 2276 __ Pop(LoadDescriptor::ReceiverRegister()); |
| 2277 EmitKeyedPropertyLoad(expr); | 2277 EmitKeyedPropertyLoad(expr); |
| 2278 context()->Plug(x0); | 2278 context()->Plug(x0); |
| 2279 } | 2279 } |
| 2280 } | 2280 } |
| 2281 | 2281 |
| 2282 | 2282 |
| 2283 void FullCodeGenerator::CallIC(Handle<Code> code, | 2283 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2284 TypeFeedbackId ast_id) { | 2284 TypeFeedbackId ast_id) { |
| 2285 ic_total_count_++; | 2285 ic_total_count_++; |
| 2286 // All calls must have a predictable size in full-codegen code to ensure that | 2286 // All calls must have a predictable size in full-codegen code to ensure that |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2302 { StackValueContext context(this); | 2302 { StackValueContext context(this); |
| 2303 EmitVariableLoad(callee->AsVariableProxy()); | 2303 EmitVariableLoad(callee->AsVariableProxy()); |
| 2304 PrepareForBailout(callee, NO_REGISTERS); | 2304 PrepareForBailout(callee, NO_REGISTERS); |
| 2305 } | 2305 } |
| 2306 // Push undefined as receiver. This is patched in the method prologue if it | 2306 // Push undefined as receiver. This is patched in the method prologue if it |
| 2307 // is a sloppy mode method. | 2307 // is a sloppy mode method. |
| 2308 __ Push(isolate()->factory()->undefined_value()); | 2308 __ Push(isolate()->factory()->undefined_value()); |
| 2309 } else { | 2309 } else { |
| 2310 // Load the function from the receiver. | 2310 // Load the function from the receiver. |
| 2311 DCHECK(callee->IsProperty()); | 2311 DCHECK(callee->IsProperty()); |
| 2312 __ Peek(LoadConvention::ReceiverRegister(), 0); | 2312 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 2313 EmitNamedPropertyLoad(callee->AsProperty()); | 2313 EmitNamedPropertyLoad(callee->AsProperty()); |
| 2314 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2314 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2315 // Push the target function under the receiver. | 2315 // Push the target function under the receiver. |
| 2316 __ Pop(x10); | 2316 __ Pop(x10); |
| 2317 __ Push(x0, x10); | 2317 __ Push(x0, x10); |
| 2318 } | 2318 } |
| 2319 | 2319 |
| 2320 EmitCall(expr, call_type); | 2320 EmitCall(expr, call_type); |
| 2321 } | 2321 } |
| 2322 | 2322 |
| 2323 | 2323 |
| 2324 // Code common for calls using the IC. | 2324 // Code common for calls using the IC. |
| 2325 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2325 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 2326 Expression* key) { | 2326 Expression* key) { |
| 2327 // Load the key. | 2327 // Load the key. |
| 2328 VisitForAccumulatorValue(key); | 2328 VisitForAccumulatorValue(key); |
| 2329 | 2329 |
| 2330 Expression* callee = expr->expression(); | 2330 Expression* callee = expr->expression(); |
| 2331 | 2331 |
| 2332 // Load the function from the receiver. | 2332 // Load the function from the receiver. |
| 2333 DCHECK(callee->IsProperty()); | 2333 DCHECK(callee->IsProperty()); |
| 2334 __ Peek(LoadConvention::ReceiverRegister(), 0); | 2334 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 2335 __ Move(LoadConvention::NameRegister(), x0); | 2335 __ Move(LoadDescriptor::NameRegister(), x0); |
| 2336 EmitKeyedPropertyLoad(callee->AsProperty()); | 2336 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2337 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2337 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2338 | 2338 |
| 2339 // Push the target function under the receiver. | 2339 // Push the target function under the receiver. |
| 2340 __ Pop(x10); | 2340 __ Pop(x10); |
| 2341 __ Push(x0, x10); | 2341 __ Push(x0, x10); |
| 2342 | 2342 |
| 2343 EmitCall(expr, CallIC::METHOD); | 2343 EmitCall(expr, CallIC::METHOD); |
| 2344 } | 2344 } |
| 2345 | 2345 |
| (...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3741 return; | 3741 return; |
| 3742 } | 3742 } |
| 3743 | 3743 |
| 3744 Comment cmnt(masm_, "[ CallRunTime"); | 3744 Comment cmnt(masm_, "[ CallRunTime"); |
| 3745 ZoneList<Expression*>* args = expr->arguments(); | 3745 ZoneList<Expression*>* args = expr->arguments(); |
| 3746 int arg_count = args->length(); | 3746 int arg_count = args->length(); |
| 3747 | 3747 |
| 3748 if (expr->is_jsruntime()) { | 3748 if (expr->is_jsruntime()) { |
| 3749 // Push the builtins object as the receiver. | 3749 // Push the builtins object as the receiver. |
| 3750 __ Ldr(x10, GlobalObjectMemOperand()); | 3750 __ Ldr(x10, GlobalObjectMemOperand()); |
| 3751 __ Ldr(LoadConvention::ReceiverRegister(), | 3751 __ Ldr(LoadDescriptor::ReceiverRegister(), |
| 3752 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); | 3752 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); |
| 3753 __ Push(LoadConvention::ReceiverRegister()); | 3753 __ Push(LoadDescriptor::ReceiverRegister()); |
| 3754 | 3754 |
| 3755 // Load the function from the receiver. | 3755 // Load the function from the receiver. |
| 3756 Handle<String> name = expr->name(); | 3756 Handle<String> name = expr->name(); |
| 3757 __ Mov(LoadConvention::NameRegister(), Operand(name)); | 3757 __ Mov(LoadDescriptor::NameRegister(), Operand(name)); |
| 3758 if (FLAG_vector_ics) { | 3758 if (FLAG_vector_ics) { |
| 3759 __ Mov(VectorLoadConvention::SlotRegister(), | 3759 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 3760 Smi::FromInt(expr->CallRuntimeFeedbackSlot())); | 3760 Smi::FromInt(expr->CallRuntimeFeedbackSlot())); |
| 3761 CallLoadIC(NOT_CONTEXTUAL); | 3761 CallLoadIC(NOT_CONTEXTUAL); |
| 3762 } else { | 3762 } else { |
| 3763 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 3763 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 3764 } | 3764 } |
| 3765 | 3765 |
| 3766 // Push the target function under the receiver. | 3766 // Push the target function under the receiver. |
| 3767 __ Pop(x10); | 3767 __ Pop(x10); |
| 3768 __ Push(x0, x10); | 3768 __ Push(x0, x10); |
| 3769 | 3769 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3929 AccumulatorValueContext context(this); | 3929 AccumulatorValueContext context(this); |
| 3930 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 3930 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 3931 } else { | 3931 } else { |
| 3932 // Reserve space for result of postfix operation. | 3932 // Reserve space for result of postfix operation. |
| 3933 if (expr->is_postfix() && !context()->IsEffect()) { | 3933 if (expr->is_postfix() && !context()->IsEffect()) { |
| 3934 __ Push(xzr); | 3934 __ Push(xzr); |
| 3935 } | 3935 } |
| 3936 if (assign_type == NAMED_PROPERTY) { | 3936 if (assign_type == NAMED_PROPERTY) { |
| 3937 // Put the object both on the stack and in the register. | 3937 // Put the object both on the stack and in the register. |
| 3938 VisitForStackValue(prop->obj()); | 3938 VisitForStackValue(prop->obj()); |
| 3939 __ Peek(LoadConvention::ReceiverRegister(), 0); | 3939 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 3940 EmitNamedPropertyLoad(prop); | 3940 EmitNamedPropertyLoad(prop); |
| 3941 } else { | 3941 } else { |
| 3942 // KEYED_PROPERTY | 3942 // KEYED_PROPERTY |
| 3943 VisitForStackValue(prop->obj()); | 3943 VisitForStackValue(prop->obj()); |
| 3944 VisitForStackValue(prop->key()); | 3944 VisitForStackValue(prop->key()); |
| 3945 __ Peek(LoadConvention::ReceiverRegister(), 1 * kPointerSize); | 3945 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
| 3946 __ Peek(LoadConvention::NameRegister(), 0); | 3946 __ Peek(LoadDescriptor::NameRegister(), 0); |
| 3947 EmitKeyedPropertyLoad(prop); | 3947 EmitKeyedPropertyLoad(prop); |
| 3948 } | 3948 } |
| 3949 } | 3949 } |
| 3950 | 3950 |
| 3951 // We need a second deoptimization point after loading the value | 3951 // We need a second deoptimization point after loading the value |
| 3952 // in case evaluating the property load my have a side effect. | 3952 // in case evaluating the property load my have a side effect. |
| 3953 if (assign_type == VARIABLE) { | 3953 if (assign_type == VARIABLE) { |
| 3954 PrepareForBailout(expr->expression(), TOS_REG); | 3954 PrepareForBailout(expr->expression(), TOS_REG); |
| 3955 } else { | 3955 } else { |
| 3956 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 3956 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4046 context()->PlugTOS(); | 4046 context()->PlugTOS(); |
| 4047 } | 4047 } |
| 4048 } else { | 4048 } else { |
| 4049 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4049 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4050 Token::ASSIGN); | 4050 Token::ASSIGN); |
| 4051 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4051 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4052 context()->Plug(x0); | 4052 context()->Plug(x0); |
| 4053 } | 4053 } |
| 4054 break; | 4054 break; |
| 4055 case NAMED_PROPERTY: { | 4055 case NAMED_PROPERTY: { |
| 4056 __ Mov(StoreConvention::NameRegister(), | 4056 __ Mov(StoreDescriptor::NameRegister(), |
| 4057 Operand(prop->key()->AsLiteral()->value())); | 4057 Operand(prop->key()->AsLiteral()->value())); |
| 4058 __ Pop(StoreConvention::ReceiverRegister()); | 4058 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4059 CallStoreIC(expr->CountStoreFeedbackId()); | 4059 CallStoreIC(expr->CountStoreFeedbackId()); |
| 4060 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4060 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4061 if (expr->is_postfix()) { | 4061 if (expr->is_postfix()) { |
| 4062 if (!context()->IsEffect()) { | 4062 if (!context()->IsEffect()) { |
| 4063 context()->PlugTOS(); | 4063 context()->PlugTOS(); |
| 4064 } | 4064 } |
| 4065 } else { | 4065 } else { |
| 4066 context()->Plug(x0); | 4066 context()->Plug(x0); |
| 4067 } | 4067 } |
| 4068 break; | 4068 break; |
| 4069 } | 4069 } |
| 4070 case KEYED_PROPERTY: { | 4070 case KEYED_PROPERTY: { |
| 4071 __ Pop(StoreConvention::NameRegister()); | 4071 __ Pop(StoreDescriptor::NameRegister()); |
| 4072 __ Pop(StoreConvention::ReceiverRegister()); | 4072 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4073 Handle<Code> ic = strict_mode() == SLOPPY | 4073 Handle<Code> ic = strict_mode() == SLOPPY |
| 4074 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4074 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4075 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4075 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4076 CallIC(ic, expr->CountStoreFeedbackId()); | 4076 CallIC(ic, expr->CountStoreFeedbackId()); |
| 4077 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4077 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4078 if (expr->is_postfix()) { | 4078 if (expr->is_postfix()) { |
| 4079 if (!context()->IsEffect()) { | 4079 if (!context()->IsEffect()) { |
| 4080 context()->PlugTOS(); | 4080 context()->PlugTOS(); |
| 4081 } | 4081 } |
| 4082 } else { | 4082 } else { |
| 4083 context()->Plug(x0); | 4083 context()->Plug(x0); |
| 4084 } | 4084 } |
| 4085 break; | 4085 break; |
| 4086 } | 4086 } |
| 4087 } | 4087 } |
| 4088 } | 4088 } |
| 4089 | 4089 |
| 4090 | 4090 |
| 4091 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4091 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4092 DCHECK(!context()->IsEffect()); | 4092 DCHECK(!context()->IsEffect()); |
| 4093 DCHECK(!context()->IsTest()); | 4093 DCHECK(!context()->IsTest()); |
| 4094 VariableProxy* proxy = expr->AsVariableProxy(); | 4094 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4095 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4095 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4096 Comment cmnt(masm_, "Global variable"); | 4096 Comment cmnt(masm_, "Global variable"); |
| 4097 __ Ldr(LoadConvention::ReceiverRegister(), GlobalObjectMemOperand()); | 4097 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
| 4098 __ Mov(LoadConvention::NameRegister(), Operand(proxy->name())); | 4098 __ Mov(LoadDescriptor::NameRegister(), Operand(proxy->name())); |
| 4099 if (FLAG_vector_ics) { | 4099 if (FLAG_vector_ics) { |
| 4100 __ Mov(VectorLoadConvention::SlotRegister(), | 4100 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 4101 Smi::FromInt(proxy->VariableFeedbackSlot())); | 4101 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 4102 } | 4102 } |
| 4103 // Use a regular load, not a contextual load, to avoid a reference | 4103 // Use a regular load, not a contextual load, to avoid a reference |
| 4104 // error. | 4104 // error. |
| 4105 CallLoadIC(NOT_CONTEXTUAL); | 4105 CallLoadIC(NOT_CONTEXTUAL); |
| 4106 PrepareForBailout(expr, TOS_REG); | 4106 PrepareForBailout(expr, TOS_REG); |
| 4107 context()->Plug(x0); | 4107 context()->Plug(x0); |
| 4108 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4108 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4109 Label done, slow; | 4109 Label done, slow; |
| 4110 | 4110 |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4385 | 4385 |
| 4386 case Yield::kDelegating: { | 4386 case Yield::kDelegating: { |
| 4387 VisitForStackValue(expr->generator_object()); | 4387 VisitForStackValue(expr->generator_object()); |
| 4388 | 4388 |
| 4389 // Initial stack layout is as follows: | 4389 // Initial stack layout is as follows: |
| 4390 // [sp + 1 * kPointerSize] iter | 4390 // [sp + 1 * kPointerSize] iter |
| 4391 // [sp + 0 * kPointerSize] g | 4391 // [sp + 0 * kPointerSize] g |
| 4392 | 4392 |
| 4393 Label l_catch, l_try, l_suspend, l_continuation, l_resume; | 4393 Label l_catch, l_try, l_suspend, l_continuation, l_resume; |
| 4394 Label l_next, l_call, l_loop; | 4394 Label l_next, l_call, l_loop; |
| 4395 Register load_receiver = LoadConvention::ReceiverRegister(); | 4395 Register load_receiver = LoadDescriptor::ReceiverRegister(); |
| 4396 Register load_name = LoadConvention::NameRegister(); | 4396 Register load_name = LoadDescriptor::NameRegister(); |
| 4397 | 4397 |
| 4398 // Initial send value is undefined. | 4398 // Initial send value is undefined. |
| 4399 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | 4399 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |
| 4400 __ B(&l_next); | 4400 __ B(&l_next); |
| 4401 | 4401 |
| 4402 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 4402 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } |
| 4403 __ Bind(&l_catch); | 4403 __ Bind(&l_catch); |
| 4404 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 4404 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); |
| 4405 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" | 4405 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" |
| 4406 __ Peek(x3, 1 * kPointerSize); // iter | 4406 __ Peek(x3, 1 * kPointerSize); // iter |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4446 | 4446 |
| 4447 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" | 4447 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" |
| 4448 __ Peek(x3, 1 * kPointerSize); // iter | 4448 __ Peek(x3, 1 * kPointerSize); // iter |
| 4449 __ Push(load_name, x3, x0); // "next", iter, received | 4449 __ Push(load_name, x3, x0); // "next", iter, received |
| 4450 | 4450 |
| 4451 // result = receiver[f](arg); | 4451 // result = receiver[f](arg); |
| 4452 __ Bind(&l_call); | 4452 __ Bind(&l_call); |
| 4453 __ Peek(load_receiver, 1 * kPointerSize); | 4453 __ Peek(load_receiver, 1 * kPointerSize); |
| 4454 __ Peek(load_name, 2 * kPointerSize); | 4454 __ Peek(load_name, 2 * kPointerSize); |
| 4455 if (FLAG_vector_ics) { | 4455 if (FLAG_vector_ics) { |
| 4456 __ Mov(VectorLoadConvention::SlotRegister(), | 4456 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 4457 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); | 4457 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); |
| 4458 } | 4458 } |
| 4459 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 4459 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 4460 CallIC(ic, TypeFeedbackId::None()); | 4460 CallIC(ic, TypeFeedbackId::None()); |
| 4461 __ Mov(x1, x0); | 4461 __ Mov(x1, x0); |
| 4462 __ Poke(x1, 2 * kPointerSize); | 4462 __ Poke(x1, 2 * kPointerSize); |
| 4463 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 4463 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 4464 __ CallStub(&stub); | 4464 __ CallStub(&stub); |
| 4465 | 4465 |
| 4466 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4466 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4467 __ Drop(1); // The function is still on the stack; drop it. | 4467 __ Drop(1); // The function is still on the stack; drop it. |
| 4468 | 4468 |
| 4469 // if (!result.done) goto l_try; | 4469 // if (!result.done) goto l_try; |
| 4470 __ Bind(&l_loop); | 4470 __ Bind(&l_loop); |
| 4471 __ Move(load_receiver, x0); | 4471 __ Move(load_receiver, x0); |
| 4472 | 4472 |
| 4473 __ Push(load_receiver); // save result | 4473 __ Push(load_receiver); // save result |
| 4474 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 4474 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
| 4475 if (FLAG_vector_ics) { | 4475 if (FLAG_vector_ics) { |
| 4476 __ Mov(VectorLoadConvention::SlotRegister(), | 4476 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 4477 Smi::FromInt(expr->DoneFeedbackSlot())); | 4477 Smi::FromInt(expr->DoneFeedbackSlot())); |
| 4478 } | 4478 } |
| 4479 CallLoadIC(NOT_CONTEXTUAL); // x0=result.done | 4479 CallLoadIC(NOT_CONTEXTUAL); // x0=result.done |
| 4480 // The ToBooleanStub argument (result.done) is in x0. | 4480 // The ToBooleanStub argument (result.done) is in x0. |
| 4481 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 4481 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 4482 CallIC(bool_ic); | 4482 CallIC(bool_ic); |
| 4483 __ Cbz(x0, &l_try); | 4483 __ Cbz(x0, &l_try); |
| 4484 | 4484 |
| 4485 // result.value | 4485 // result.value |
| 4486 __ Pop(load_receiver); // result | 4486 __ Pop(load_receiver); // result |
| 4487 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" | 4487 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
| 4488 if (FLAG_vector_ics) { | 4488 if (FLAG_vector_ics) { |
| 4489 __ Mov(VectorLoadConvention::SlotRegister(), | 4489 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 4490 Smi::FromInt(expr->ValueFeedbackSlot())); | 4490 Smi::FromInt(expr->ValueFeedbackSlot())); |
| 4491 } | 4491 } |
| 4492 CallLoadIC(NOT_CONTEXTUAL); // x0=result.value | 4492 CallLoadIC(NOT_CONTEXTUAL); // x0=result.value |
| 4493 context()->DropAndPlug(2, x0); // drop iter and g | 4493 context()->DropAndPlug(2, x0); // drop iter and g |
| 4494 break; | 4494 break; |
| 4495 } | 4495 } |
| 4496 } | 4496 } |
| 4497 } | 4497 } |
| 4498 | 4498 |
| 4499 | 4499 |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4911 return previous_; | 4911 return previous_; |
| 4912 } | 4912 } |
| 4913 | 4913 |
| 4914 | 4914 |
| 4915 #undef __ | 4915 #undef __ |
| 4916 | 4916 |
| 4917 | 4917 |
| 4918 } } // namespace v8::internal | 4918 } } // namespace v8::internal |
| 4919 | 4919 |
| 4920 #endif // V8_TARGET_ARCH_ARM64 | 4920 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |