| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 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 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1355 __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); | 1355 __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); |
| 1356 __ j(not_equal, slow); | 1356 __ j(not_equal, slow); |
| 1357 // Load next context in chain. | 1357 // Load next context in chain. |
| 1358 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1358 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
| 1359 __ jmp(&next); | 1359 __ jmp(&next); |
| 1360 __ bind(&fast); | 1360 __ bind(&fast); |
| 1361 } | 1361 } |
| 1362 | 1362 |
| 1363 // All extension objects were empty and it is safe to use a global | 1363 // All extension objects were empty and it is safe to use a global |
| 1364 // load IC call. | 1364 // load IC call. |
| 1365 __ movp(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); | 1365 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 1366 __ Move(LoadConvention::NameRegister(), proxy->var()->name()); | 1366 __ Move(LoadDescriptor::NameRegister(), proxy->var()->name()); |
| 1367 if (FLAG_vector_ics) { | 1367 if (FLAG_vector_ics) { |
| 1368 __ Move(VectorLoadConvention::SlotRegister(), | 1368 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 1369 Smi::FromInt(proxy->VariableFeedbackSlot())); | 1369 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 1370 } | 1370 } |
| 1371 | 1371 |
| 1372 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | 1372 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1373 ? NOT_CONTEXTUAL | 1373 ? NOT_CONTEXTUAL |
| 1374 : CONTEXTUAL; | 1374 : CONTEXTUAL; |
| 1375 CallLoadIC(mode); | 1375 CallLoadIC(mode); |
| 1376 } | 1376 } |
| 1377 | 1377 |
| 1378 | 1378 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1441 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1442 // Record position before possible IC call. | 1442 // Record position before possible IC call. |
| 1443 SetSourcePosition(proxy->position()); | 1443 SetSourcePosition(proxy->position()); |
| 1444 Variable* var = proxy->var(); | 1444 Variable* var = proxy->var(); |
| 1445 | 1445 |
| 1446 // Three cases: global variables, lookup variables, and all other types of | 1446 // Three cases: global variables, lookup variables, and all other types of |
| 1447 // variables. | 1447 // variables. |
| 1448 switch (var->location()) { | 1448 switch (var->location()) { |
| 1449 case Variable::UNALLOCATED: { | 1449 case Variable::UNALLOCATED: { |
| 1450 Comment cmnt(masm_, "[ Global variable"); | 1450 Comment cmnt(masm_, "[ Global variable"); |
| 1451 __ Move(LoadConvention::NameRegister(), var->name()); | 1451 __ Move(LoadDescriptor::NameRegister(), var->name()); |
| 1452 __ movp(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); | 1452 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 1453 if (FLAG_vector_ics) { | 1453 if (FLAG_vector_ics) { |
| 1454 __ Move(VectorLoadConvention::SlotRegister(), | 1454 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 1455 Smi::FromInt(proxy->VariableFeedbackSlot())); | 1455 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 1456 } | 1456 } |
| 1457 CallLoadIC(CONTEXTUAL); | 1457 CallLoadIC(CONTEXTUAL); |
| 1458 context()->Plug(rax); | 1458 context()->Plug(rax); |
| 1459 break; | 1459 break; |
| 1460 } | 1460 } |
| 1461 | 1461 |
| 1462 case Variable::PARAMETER: | 1462 case Variable::PARAMETER: |
| 1463 case Variable::LOCAL: | 1463 case Variable::LOCAL: |
| 1464 case Variable::CONTEXT: { | 1464 case Variable::CONTEXT: { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1659 switch (property->kind()) { | 1659 switch (property->kind()) { |
| 1660 case ObjectLiteral::Property::CONSTANT: | 1660 case ObjectLiteral::Property::CONSTANT: |
| 1661 UNREACHABLE(); | 1661 UNREACHABLE(); |
| 1662 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1662 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1663 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1663 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1664 // Fall through. | 1664 // Fall through. |
| 1665 case ObjectLiteral::Property::COMPUTED: | 1665 case ObjectLiteral::Property::COMPUTED: |
| 1666 if (key->value()->IsInternalizedString()) { | 1666 if (key->value()->IsInternalizedString()) { |
| 1667 if (property->emit_store()) { | 1667 if (property->emit_store()) { |
| 1668 VisitForAccumulatorValue(value); | 1668 VisitForAccumulatorValue(value); |
| 1669 DCHECK(StoreConvention::ValueRegister().is(rax)); | 1669 DCHECK(StoreDescriptor::ValueRegister().is(rax)); |
| 1670 __ Move(StoreConvention::NameRegister(), key->value()); | 1670 __ Move(StoreDescriptor::NameRegister(), key->value()); |
| 1671 __ movp(StoreConvention::ReceiverRegister(), Operand(rsp, 0)); | 1671 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1672 CallStoreIC(key->LiteralFeedbackId()); | 1672 CallStoreIC(key->LiteralFeedbackId()); |
| 1673 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1673 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1674 } else { | 1674 } else { |
| 1675 VisitForEffect(value); | 1675 VisitForEffect(value); |
| 1676 } | 1676 } |
| 1677 break; | 1677 break; |
| 1678 } | 1678 } |
| 1679 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1679 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1680 VisitForStackValue(key); | 1680 VisitForStackValue(key); |
| 1681 VisitForStackValue(value); | 1681 VisitForStackValue(value); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1840 | 1840 |
| 1841 // Evaluate LHS expression. | 1841 // Evaluate LHS expression. |
| 1842 switch (assign_type) { | 1842 switch (assign_type) { |
| 1843 case VARIABLE: | 1843 case VARIABLE: |
| 1844 // Nothing to do here. | 1844 // Nothing to do here. |
| 1845 break; | 1845 break; |
| 1846 case NAMED_PROPERTY: | 1846 case NAMED_PROPERTY: |
| 1847 if (expr->is_compound()) { | 1847 if (expr->is_compound()) { |
| 1848 // We need the receiver both on the stack and in the register. | 1848 // We need the receiver both on the stack and in the register. |
| 1849 VisitForStackValue(property->obj()); | 1849 VisitForStackValue(property->obj()); |
| 1850 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); | 1850 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1851 } else { | 1851 } else { |
| 1852 VisitForStackValue(property->obj()); | 1852 VisitForStackValue(property->obj()); |
| 1853 } | 1853 } |
| 1854 break; | 1854 break; |
| 1855 case KEYED_PROPERTY: { | 1855 case KEYED_PROPERTY: { |
| 1856 if (expr->is_compound()) { | 1856 if (expr->is_compound()) { |
| 1857 VisitForStackValue(property->obj()); | 1857 VisitForStackValue(property->obj()); |
| 1858 VisitForStackValue(property->key()); | 1858 VisitForStackValue(property->key()); |
| 1859 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, kPointerSize)); | 1859 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); |
| 1860 __ movp(LoadConvention::NameRegister(), Operand(rsp, 0)); | 1860 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0)); |
| 1861 } else { | 1861 } else { |
| 1862 VisitForStackValue(property->obj()); | 1862 VisitForStackValue(property->obj()); |
| 1863 VisitForStackValue(property->key()); | 1863 VisitForStackValue(property->key()); |
| 1864 } | 1864 } |
| 1865 break; | 1865 break; |
| 1866 } | 1866 } |
| 1867 } | 1867 } |
| 1868 | 1868 |
| 1869 // For compound assignments we need another deoptimization point after the | 1869 // For compound assignments we need another deoptimization point after the |
| 1870 // variable/property load. | 1870 // variable/property load. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1991 | 1991 |
| 1992 case Yield::kDelegating: { | 1992 case Yield::kDelegating: { |
| 1993 VisitForStackValue(expr->generator_object()); | 1993 VisitForStackValue(expr->generator_object()); |
| 1994 | 1994 |
| 1995 // Initial stack layout is as follows: | 1995 // Initial stack layout is as follows: |
| 1996 // [sp + 1 * kPointerSize] iter | 1996 // [sp + 1 * kPointerSize] iter |
| 1997 // [sp + 0 * kPointerSize] g | 1997 // [sp + 0 * kPointerSize] g |
| 1998 | 1998 |
| 1999 Label l_catch, l_try, l_suspend, l_continuation, l_resume; | 1999 Label l_catch, l_try, l_suspend, l_continuation, l_resume; |
| 2000 Label l_next, l_call, l_loop; | 2000 Label l_next, l_call, l_loop; |
| 2001 Register load_receiver = LoadConvention::ReceiverRegister(); | 2001 Register load_receiver = LoadDescriptor::ReceiverRegister(); |
| 2002 Register load_name = LoadConvention::NameRegister(); | 2002 Register load_name = LoadDescriptor::NameRegister(); |
| 2003 | 2003 |
| 2004 // Initial send value is undefined. | 2004 // Initial send value is undefined. |
| 2005 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 2005 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
| 2006 __ jmp(&l_next); | 2006 __ jmp(&l_next); |
| 2007 | 2007 |
| 2008 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 2008 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } |
| 2009 __ bind(&l_catch); | 2009 __ bind(&l_catch); |
| 2010 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 2010 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); |
| 2011 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" | 2011 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" |
| 2012 __ Push(load_name); | 2012 __ Push(load_name); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2049 | 2049 |
| 2050 __ LoadRoot(load_name, Heap::knext_stringRootIndex); | 2050 __ LoadRoot(load_name, Heap::knext_stringRootIndex); |
| 2051 __ Push(load_name); // "next" | 2051 __ Push(load_name); // "next" |
| 2052 __ Push(Operand(rsp, 2 * kPointerSize)); // iter | 2052 __ Push(Operand(rsp, 2 * kPointerSize)); // iter |
| 2053 __ Push(rax); // received | 2053 __ Push(rax); // received |
| 2054 | 2054 |
| 2055 // result = receiver[f](arg); | 2055 // result = receiver[f](arg); |
| 2056 __ bind(&l_call); | 2056 __ bind(&l_call); |
| 2057 __ movp(load_receiver, Operand(rsp, kPointerSize)); | 2057 __ movp(load_receiver, Operand(rsp, kPointerSize)); |
| 2058 if (FLAG_vector_ics) { | 2058 if (FLAG_vector_ics) { |
| 2059 __ Move(VectorLoadConvention::SlotRegister(), | 2059 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 2060 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); | 2060 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); |
| 2061 } | 2061 } |
| 2062 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2062 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2063 CallIC(ic, TypeFeedbackId::None()); | 2063 CallIC(ic, TypeFeedbackId::None()); |
| 2064 __ movp(rdi, rax); | 2064 __ movp(rdi, rax); |
| 2065 __ movp(Operand(rsp, 2 * kPointerSize), rdi); | 2065 __ movp(Operand(rsp, 2 * kPointerSize), rdi); |
| 2066 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2066 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 2067 __ CallStub(&stub); | 2067 __ CallStub(&stub); |
| 2068 | 2068 |
| 2069 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2069 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2070 __ Drop(1); // The function is still on the stack; drop it. | 2070 __ Drop(1); // The function is still on the stack; drop it. |
| 2071 | 2071 |
| 2072 // if (!result.done) goto l_try; | 2072 // if (!result.done) goto l_try; |
| 2073 __ bind(&l_loop); | 2073 __ bind(&l_loop); |
| 2074 __ Move(load_receiver, rax); | 2074 __ Move(load_receiver, rax); |
| 2075 __ Push(load_receiver); // save result | 2075 __ Push(load_receiver); // save result |
| 2076 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 2076 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
| 2077 if (FLAG_vector_ics) { | 2077 if (FLAG_vector_ics) { |
| 2078 __ Move(VectorLoadConvention::SlotRegister(), | 2078 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 2079 Smi::FromInt(expr->DoneFeedbackSlot())); | 2079 Smi::FromInt(expr->DoneFeedbackSlot())); |
| 2080 } | 2080 } |
| 2081 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done | 2081 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done |
| 2082 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2082 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2083 CallIC(bool_ic); | 2083 CallIC(bool_ic); |
| 2084 __ testp(result_register(), result_register()); | 2084 __ testp(result_register(), result_register()); |
| 2085 __ j(zero, &l_try); | 2085 __ j(zero, &l_try); |
| 2086 | 2086 |
| 2087 // result.value | 2087 // result.value |
| 2088 __ Pop(load_receiver); // result | 2088 __ Pop(load_receiver); // result |
| 2089 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" | 2089 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
| 2090 if (FLAG_vector_ics) { | 2090 if (FLAG_vector_ics) { |
| 2091 __ Move(VectorLoadConvention::SlotRegister(), | 2091 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 2092 Smi::FromInt(expr->ValueFeedbackSlot())); | 2092 Smi::FromInt(expr->ValueFeedbackSlot())); |
| 2093 } | 2093 } |
| 2094 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax | 2094 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax |
| 2095 context()->DropAndPlug(2, rax); // drop iter and g | 2095 context()->DropAndPlug(2, rax); // drop iter and g |
| 2096 break; | 2096 break; |
| 2097 } | 2097 } |
| 2098 } | 2098 } |
| 2099 } | 2099 } |
| 2100 | 2100 |
| 2101 | 2101 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2244 // Only the value field needs a write barrier, as the other values are in the | 2244 // Only the value field needs a write barrier, as the other values are in the |
| 2245 // root set. | 2245 // root set. |
| 2246 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, | 2246 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, |
| 2247 rcx, rdx, kDontSaveFPRegs); | 2247 rcx, rdx, kDontSaveFPRegs); |
| 2248 } | 2248 } |
| 2249 | 2249 |
| 2250 | 2250 |
| 2251 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2251 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2252 SetSourcePosition(prop->position()); | 2252 SetSourcePosition(prop->position()); |
| 2253 Literal* key = prop->key()->AsLiteral(); | 2253 Literal* key = prop->key()->AsLiteral(); |
| 2254 __ Move(LoadConvention::NameRegister(), key->value()); | 2254 __ Move(LoadDescriptor::NameRegister(), key->value()); |
| 2255 if (FLAG_vector_ics) { | 2255 if (FLAG_vector_ics) { |
| 2256 __ Move(VectorLoadConvention::SlotRegister(), | 2256 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 2257 Smi::FromInt(prop->PropertyFeedbackSlot())); | 2257 Smi::FromInt(prop->PropertyFeedbackSlot())); |
| 2258 CallLoadIC(NOT_CONTEXTUAL); | 2258 CallLoadIC(NOT_CONTEXTUAL); |
| 2259 } else { | 2259 } else { |
| 2260 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2260 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2261 } | 2261 } |
| 2262 } | 2262 } |
| 2263 | 2263 |
| 2264 | 2264 |
| 2265 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2265 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2266 SetSourcePosition(prop->position()); | 2266 SetSourcePosition(prop->position()); |
| 2267 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2267 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2268 if (FLAG_vector_ics) { | 2268 if (FLAG_vector_ics) { |
| 2269 __ Move(VectorLoadConvention::SlotRegister(), | 2269 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 2270 Smi::FromInt(prop->PropertyFeedbackSlot())); | 2270 Smi::FromInt(prop->PropertyFeedbackSlot())); |
| 2271 CallIC(ic); | 2271 CallIC(ic); |
| 2272 } else { | 2272 } else { |
| 2273 CallIC(ic, prop->PropertyFeedbackId()); | 2273 CallIC(ic, prop->PropertyFeedbackId()); |
| 2274 } | 2274 } |
| 2275 } | 2275 } |
| 2276 | 2276 |
| 2277 | 2277 |
| 2278 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2278 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2279 Token::Value op, | 2279 Token::Value op, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2365 switch (assign_type) { | 2365 switch (assign_type) { |
| 2366 case VARIABLE: { | 2366 case VARIABLE: { |
| 2367 Variable* var = expr->AsVariableProxy()->var(); | 2367 Variable* var = expr->AsVariableProxy()->var(); |
| 2368 EffectContext context(this); | 2368 EffectContext context(this); |
| 2369 EmitVariableAssignment(var, Token::ASSIGN); | 2369 EmitVariableAssignment(var, Token::ASSIGN); |
| 2370 break; | 2370 break; |
| 2371 } | 2371 } |
| 2372 case NAMED_PROPERTY: { | 2372 case NAMED_PROPERTY: { |
| 2373 __ Push(rax); // Preserve value. | 2373 __ Push(rax); // Preserve value. |
| 2374 VisitForAccumulatorValue(prop->obj()); | 2374 VisitForAccumulatorValue(prop->obj()); |
| 2375 __ Move(StoreConvention::ReceiverRegister(), rax); | 2375 __ Move(StoreDescriptor::ReceiverRegister(), rax); |
| 2376 __ Pop(StoreConvention::ValueRegister()); // Restore value. | 2376 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2377 __ Move(StoreConvention::NameRegister(), | 2377 __ Move(StoreDescriptor::NameRegister(), |
| 2378 prop->key()->AsLiteral()->value()); | 2378 prop->key()->AsLiteral()->value()); |
| 2379 CallStoreIC(); | 2379 CallStoreIC(); |
| 2380 break; | 2380 break; |
| 2381 } | 2381 } |
| 2382 case KEYED_PROPERTY: { | 2382 case KEYED_PROPERTY: { |
| 2383 __ Push(rax); // Preserve value. | 2383 __ Push(rax); // Preserve value. |
| 2384 VisitForStackValue(prop->obj()); | 2384 VisitForStackValue(prop->obj()); |
| 2385 VisitForAccumulatorValue(prop->key()); | 2385 VisitForAccumulatorValue(prop->key()); |
| 2386 __ Move(StoreConvention::NameRegister(), rax); | 2386 __ Move(StoreDescriptor::NameRegister(), rax); |
| 2387 __ Pop(StoreConvention::ReceiverRegister()); | 2387 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2388 __ Pop(StoreConvention::ValueRegister()); // Restore value. | 2388 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2389 Handle<Code> ic = strict_mode() == SLOPPY | 2389 Handle<Code> ic = strict_mode() == SLOPPY |
| 2390 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2390 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2391 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2391 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2392 CallIC(ic); | 2392 CallIC(ic); |
| 2393 break; | 2393 break; |
| 2394 } | 2394 } |
| 2395 } | 2395 } |
| 2396 context()->Plug(rax); | 2396 context()->Plug(rax); |
| 2397 } | 2397 } |
| 2398 | 2398 |
| 2399 | 2399 |
| 2400 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2400 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2401 Variable* var, MemOperand location) { | 2401 Variable* var, MemOperand location) { |
| 2402 __ movp(location, rax); | 2402 __ movp(location, rax); |
| 2403 if (var->IsContextSlot()) { | 2403 if (var->IsContextSlot()) { |
| 2404 __ movp(rdx, rax); | 2404 __ movp(rdx, rax); |
| 2405 __ RecordWriteContextSlot( | 2405 __ RecordWriteContextSlot( |
| 2406 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); | 2406 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); |
| 2407 } | 2407 } |
| 2408 } | 2408 } |
| 2409 | 2409 |
| 2410 | 2410 |
| 2411 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2411 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 2412 Token::Value op) { | 2412 Token::Value op) { |
| 2413 if (var->IsUnallocated()) { | 2413 if (var->IsUnallocated()) { |
| 2414 // Global var, const, or let. | 2414 // Global var, const, or let. |
| 2415 __ Move(StoreConvention::NameRegister(), var->name()); | 2415 __ Move(StoreDescriptor::NameRegister(), var->name()); |
| 2416 __ movp(StoreConvention::ReceiverRegister(), GlobalObjectOperand()); | 2416 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2417 CallStoreIC(); | 2417 CallStoreIC(); |
| 2418 | 2418 |
| 2419 } else if (op == Token::INIT_CONST_LEGACY) { | 2419 } else if (op == Token::INIT_CONST_LEGACY) { |
| 2420 // Const initializers need a write barrier. | 2420 // Const initializers need a write barrier. |
| 2421 DCHECK(!var->IsParameter()); // No const parameters. | 2421 DCHECK(!var->IsParameter()); // No const parameters. |
| 2422 if (var->IsLookupSlot()) { | 2422 if (var->IsLookupSlot()) { |
| 2423 __ Push(rax); | 2423 __ Push(rax); |
| 2424 __ Push(rsi); | 2424 __ Push(rsi); |
| 2425 __ Push(var->name()); | 2425 __ Push(var->name()); |
| 2426 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); | 2426 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2476 | 2476 |
| 2477 | 2477 |
| 2478 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2478 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2479 // Assignment to a property, using a named store IC. | 2479 // Assignment to a property, using a named store IC. |
| 2480 Property* prop = expr->target()->AsProperty(); | 2480 Property* prop = expr->target()->AsProperty(); |
| 2481 DCHECK(prop != NULL); | 2481 DCHECK(prop != NULL); |
| 2482 DCHECK(prop->key()->IsLiteral()); | 2482 DCHECK(prop->key()->IsLiteral()); |
| 2483 | 2483 |
| 2484 // Record source code position before IC call. | 2484 // Record source code position before IC call. |
| 2485 SetSourcePosition(expr->position()); | 2485 SetSourcePosition(expr->position()); |
| 2486 __ Move(StoreConvention::NameRegister(), prop->key()->AsLiteral()->value()); | 2486 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
| 2487 __ Pop(StoreConvention::ReceiverRegister()); | 2487 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2488 CallStoreIC(expr->AssignmentFeedbackId()); | 2488 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2489 | 2489 |
| 2490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2491 context()->Plug(rax); | 2491 context()->Plug(rax); |
| 2492 } | 2492 } |
| 2493 | 2493 |
| 2494 | 2494 |
| 2495 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2495 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2496 // Assignment to a property, using a keyed store IC. | 2496 // Assignment to a property, using a keyed store IC. |
| 2497 | 2497 |
| 2498 __ Pop(StoreConvention::NameRegister()); // Key. | 2498 __ Pop(StoreDescriptor::NameRegister()); // Key. |
| 2499 __ Pop(StoreConvention::ReceiverRegister()); | 2499 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2500 DCHECK(StoreConvention::ValueRegister().is(rax)); | 2500 DCHECK(StoreDescriptor::ValueRegister().is(rax)); |
| 2501 // Record source code position before IC call. | 2501 // Record source code position before IC call. |
| 2502 SetSourcePosition(expr->position()); | 2502 SetSourcePosition(expr->position()); |
| 2503 Handle<Code> ic = strict_mode() == SLOPPY | 2503 Handle<Code> ic = strict_mode() == SLOPPY |
| 2504 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2504 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2505 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2505 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2506 CallIC(ic, expr->AssignmentFeedbackId()); | 2506 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2507 | 2507 |
| 2508 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2508 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2509 context()->Plug(rax); | 2509 context()->Plug(rax); |
| 2510 } | 2510 } |
| 2511 | 2511 |
| 2512 | 2512 |
| 2513 void FullCodeGenerator::VisitProperty(Property* expr) { | 2513 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2514 Comment cmnt(masm_, "[ Property"); | 2514 Comment cmnt(masm_, "[ Property"); |
| 2515 Expression* key = expr->key(); | 2515 Expression* key = expr->key(); |
| 2516 | 2516 |
| 2517 if (key->IsPropertyName()) { | 2517 if (key->IsPropertyName()) { |
| 2518 VisitForAccumulatorValue(expr->obj()); | 2518 VisitForAccumulatorValue(expr->obj()); |
| 2519 DCHECK(!rax.is(LoadConvention::ReceiverRegister())); | 2519 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister())); |
| 2520 __ movp(LoadConvention::ReceiverRegister(), rax); | 2520 __ movp(LoadDescriptor::ReceiverRegister(), rax); |
| 2521 EmitNamedPropertyLoad(expr); | 2521 EmitNamedPropertyLoad(expr); |
| 2522 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2522 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2523 context()->Plug(rax); | 2523 context()->Plug(rax); |
| 2524 } else { | 2524 } else { |
| 2525 VisitForStackValue(expr->obj()); | 2525 VisitForStackValue(expr->obj()); |
| 2526 VisitForAccumulatorValue(expr->key()); | 2526 VisitForAccumulatorValue(expr->key()); |
| 2527 __ Move(LoadConvention::NameRegister(), rax); | 2527 __ Move(LoadDescriptor::NameRegister(), rax); |
| 2528 __ Pop(LoadConvention::ReceiverRegister()); | 2528 __ Pop(LoadDescriptor::ReceiverRegister()); |
| 2529 EmitKeyedPropertyLoad(expr); | 2529 EmitKeyedPropertyLoad(expr); |
| 2530 context()->Plug(rax); | 2530 context()->Plug(rax); |
| 2531 } | 2531 } |
| 2532 } | 2532 } |
| 2533 | 2533 |
| 2534 | 2534 |
| 2535 void FullCodeGenerator::CallIC(Handle<Code> code, | 2535 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2536 TypeFeedbackId ast_id) { | 2536 TypeFeedbackId ast_id) { |
| 2537 ic_total_count_++; | 2537 ic_total_count_++; |
| 2538 __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2538 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2551 { StackValueContext context(this); | 2551 { StackValueContext context(this); |
| 2552 EmitVariableLoad(callee->AsVariableProxy()); | 2552 EmitVariableLoad(callee->AsVariableProxy()); |
| 2553 PrepareForBailout(callee, NO_REGISTERS); | 2553 PrepareForBailout(callee, NO_REGISTERS); |
| 2554 } | 2554 } |
| 2555 // Push undefined as receiver. This is patched in the method prologue if it | 2555 // Push undefined as receiver. This is patched in the method prologue if it |
| 2556 // is a sloppy mode method. | 2556 // is a sloppy mode method. |
| 2557 __ Push(isolate()->factory()->undefined_value()); | 2557 __ Push(isolate()->factory()->undefined_value()); |
| 2558 } else { | 2558 } else { |
| 2559 // Load the function from the receiver. | 2559 // Load the function from the receiver. |
| 2560 DCHECK(callee->IsProperty()); | 2560 DCHECK(callee->IsProperty()); |
| 2561 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); | 2561 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 2562 EmitNamedPropertyLoad(callee->AsProperty()); | 2562 EmitNamedPropertyLoad(callee->AsProperty()); |
| 2563 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2563 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2564 // Push the target function under the receiver. | 2564 // Push the target function under the receiver. |
| 2565 __ Push(Operand(rsp, 0)); | 2565 __ Push(Operand(rsp, 0)); |
| 2566 __ movp(Operand(rsp, kPointerSize), rax); | 2566 __ movp(Operand(rsp, kPointerSize), rax); |
| 2567 } | 2567 } |
| 2568 | 2568 |
| 2569 EmitCall(expr, call_type); | 2569 EmitCall(expr, call_type); |
| 2570 } | 2570 } |
| 2571 | 2571 |
| 2572 | 2572 |
| 2573 // Common code for calls using the IC. | 2573 // Common code for calls using the IC. |
| 2574 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2574 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 2575 Expression* key) { | 2575 Expression* key) { |
| 2576 // Load the key. | 2576 // Load the key. |
| 2577 VisitForAccumulatorValue(key); | 2577 VisitForAccumulatorValue(key); |
| 2578 | 2578 |
| 2579 Expression* callee = expr->expression(); | 2579 Expression* callee = expr->expression(); |
| 2580 | 2580 |
| 2581 // Load the function from the receiver. | 2581 // Load the function from the receiver. |
| 2582 DCHECK(callee->IsProperty()); | 2582 DCHECK(callee->IsProperty()); |
| 2583 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); | 2583 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 2584 __ Move(LoadConvention::NameRegister(), rax); | 2584 __ Move(LoadDescriptor::NameRegister(), rax); |
| 2585 EmitKeyedPropertyLoad(callee->AsProperty()); | 2585 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2586 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2586 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2587 | 2587 |
| 2588 // Push the target function under the receiver. | 2588 // Push the target function under the receiver. |
| 2589 __ Push(Operand(rsp, 0)); | 2589 __ Push(Operand(rsp, 0)); |
| 2590 __ movp(Operand(rsp, kPointerSize), rax); | 2590 __ movp(Operand(rsp, kPointerSize), rax); |
| 2591 | 2591 |
| 2592 EmitCall(expr, CallIC::METHOD); | 2592 EmitCall(expr, CallIC::METHOD); |
| 2593 } | 2593 } |
| 2594 | 2594 |
| (...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4052 Comment cmnt(masm_, "[ CallRuntime"); | 4052 Comment cmnt(masm_, "[ CallRuntime"); |
| 4053 ZoneList<Expression*>* args = expr->arguments(); | 4053 ZoneList<Expression*>* args = expr->arguments(); |
| 4054 int arg_count = args->length(); | 4054 int arg_count = args->length(); |
| 4055 | 4055 |
| 4056 if (expr->is_jsruntime()) { | 4056 if (expr->is_jsruntime()) { |
| 4057 // Push the builtins object as receiver. | 4057 // Push the builtins object as receiver. |
| 4058 __ movp(rax, GlobalObjectOperand()); | 4058 __ movp(rax, GlobalObjectOperand()); |
| 4059 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 4059 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
| 4060 | 4060 |
| 4061 // Load the function from the receiver. | 4061 // Load the function from the receiver. |
| 4062 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); | 4062 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 4063 __ Move(LoadConvention::NameRegister(), expr->name()); | 4063 __ Move(LoadDescriptor::NameRegister(), expr->name()); |
| 4064 if (FLAG_vector_ics) { | 4064 if (FLAG_vector_ics) { |
| 4065 __ Move(VectorLoadConvention::SlotRegister(), | 4065 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 4066 Smi::FromInt(expr->CallRuntimeFeedbackSlot())); | 4066 Smi::FromInt(expr->CallRuntimeFeedbackSlot())); |
| 4067 CallLoadIC(NOT_CONTEXTUAL); | 4067 CallLoadIC(NOT_CONTEXTUAL); |
| 4068 } else { | 4068 } else { |
| 4069 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4069 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4070 } | 4070 } |
| 4071 | 4071 |
| 4072 // Push the target function under the receiver. | 4072 // Push the target function under the receiver. |
| 4073 __ Push(Operand(rsp, 0)); | 4073 __ Push(Operand(rsp, 0)); |
| 4074 __ movp(Operand(rsp, kPointerSize), rax); | 4074 __ movp(Operand(rsp, kPointerSize), rax); |
| 4075 | 4075 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4238 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4238 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4239 AccumulatorValueContext context(this); | 4239 AccumulatorValueContext context(this); |
| 4240 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4240 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4241 } else { | 4241 } else { |
| 4242 // Reserve space for result of postfix operation. | 4242 // Reserve space for result of postfix operation. |
| 4243 if (expr->is_postfix() && !context()->IsEffect()) { | 4243 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4244 __ Push(Smi::FromInt(0)); | 4244 __ Push(Smi::FromInt(0)); |
| 4245 } | 4245 } |
| 4246 if (assign_type == NAMED_PROPERTY) { | 4246 if (assign_type == NAMED_PROPERTY) { |
| 4247 VisitForStackValue(prop->obj()); | 4247 VisitForStackValue(prop->obj()); |
| 4248 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); | 4248 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 4249 EmitNamedPropertyLoad(prop); | 4249 EmitNamedPropertyLoad(prop); |
| 4250 } else { | 4250 } else { |
| 4251 VisitForStackValue(prop->obj()); | 4251 VisitForStackValue(prop->obj()); |
| 4252 VisitForStackValue(prop->key()); | 4252 VisitForStackValue(prop->key()); |
| 4253 // Leave receiver on stack | 4253 // Leave receiver on stack |
| 4254 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, kPointerSize)); | 4254 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); |
| 4255 // Copy of key, needed for later store. | 4255 // Copy of key, needed for later store. |
| 4256 __ movp(LoadConvention::NameRegister(), Operand(rsp, 0)); | 4256 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0)); |
| 4257 EmitKeyedPropertyLoad(prop); | 4257 EmitKeyedPropertyLoad(prop); |
| 4258 } | 4258 } |
| 4259 } | 4259 } |
| 4260 | 4260 |
| 4261 // We need a second deoptimization point after loading the value | 4261 // We need a second deoptimization point after loading the value |
| 4262 // in case evaluating the property load my have a side effect. | 4262 // in case evaluating the property load my have a side effect. |
| 4263 if (assign_type == VARIABLE) { | 4263 if (assign_type == VARIABLE) { |
| 4264 PrepareForBailout(expr->expression(), TOS_REG); | 4264 PrepareForBailout(expr->expression(), TOS_REG); |
| 4265 } else { | 4265 } else { |
| 4266 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4266 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4358 } | 4358 } |
| 4359 } else { | 4359 } else { |
| 4360 // Perform the assignment as if via '='. | 4360 // Perform the assignment as if via '='. |
| 4361 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4361 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4362 Token::ASSIGN); | 4362 Token::ASSIGN); |
| 4363 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4363 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4364 context()->Plug(rax); | 4364 context()->Plug(rax); |
| 4365 } | 4365 } |
| 4366 break; | 4366 break; |
| 4367 case NAMED_PROPERTY: { | 4367 case NAMED_PROPERTY: { |
| 4368 __ Move(StoreConvention::NameRegister(), | 4368 __ Move(StoreDescriptor::NameRegister(), |
| 4369 prop->key()->AsLiteral()->value()); | 4369 prop->key()->AsLiteral()->value()); |
| 4370 __ Pop(StoreConvention::ReceiverRegister()); | 4370 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4371 CallStoreIC(expr->CountStoreFeedbackId()); | 4371 CallStoreIC(expr->CountStoreFeedbackId()); |
| 4372 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4372 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4373 if (expr->is_postfix()) { | 4373 if (expr->is_postfix()) { |
| 4374 if (!context()->IsEffect()) { | 4374 if (!context()->IsEffect()) { |
| 4375 context()->PlugTOS(); | 4375 context()->PlugTOS(); |
| 4376 } | 4376 } |
| 4377 } else { | 4377 } else { |
| 4378 context()->Plug(rax); | 4378 context()->Plug(rax); |
| 4379 } | 4379 } |
| 4380 break; | 4380 break; |
| 4381 } | 4381 } |
| 4382 case KEYED_PROPERTY: { | 4382 case KEYED_PROPERTY: { |
| 4383 __ Pop(StoreConvention::NameRegister()); | 4383 __ Pop(StoreDescriptor::NameRegister()); |
| 4384 __ Pop(StoreConvention::ReceiverRegister()); | 4384 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4385 Handle<Code> ic = strict_mode() == SLOPPY | 4385 Handle<Code> ic = strict_mode() == SLOPPY |
| 4386 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4386 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4387 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4387 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4388 CallIC(ic, expr->CountStoreFeedbackId()); | 4388 CallIC(ic, expr->CountStoreFeedbackId()); |
| 4389 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4389 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4390 if (expr->is_postfix()) { | 4390 if (expr->is_postfix()) { |
| 4391 if (!context()->IsEffect()) { | 4391 if (!context()->IsEffect()) { |
| 4392 context()->PlugTOS(); | 4392 context()->PlugTOS(); |
| 4393 } | 4393 } |
| 4394 } else { | 4394 } else { |
| 4395 context()->Plug(rax); | 4395 context()->Plug(rax); |
| 4396 } | 4396 } |
| 4397 break; | 4397 break; |
| 4398 } | 4398 } |
| 4399 } | 4399 } |
| 4400 } | 4400 } |
| 4401 | 4401 |
| 4402 | 4402 |
| 4403 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4403 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4404 VariableProxy* proxy = expr->AsVariableProxy(); | 4404 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4405 DCHECK(!context()->IsEffect()); | 4405 DCHECK(!context()->IsEffect()); |
| 4406 DCHECK(!context()->IsTest()); | 4406 DCHECK(!context()->IsTest()); |
| 4407 | 4407 |
| 4408 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4408 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4409 Comment cmnt(masm_, "[ Global variable"); | 4409 Comment cmnt(masm_, "[ Global variable"); |
| 4410 __ Move(LoadConvention::NameRegister(), proxy->name()); | 4410 __ Move(LoadDescriptor::NameRegister(), proxy->name()); |
| 4411 __ movp(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); | 4411 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 4412 if (FLAG_vector_ics) { | 4412 if (FLAG_vector_ics) { |
| 4413 __ Move(VectorLoadConvention::SlotRegister(), | 4413 __ Move(VectorLoadICDescriptor::SlotRegister(), |
| 4414 Smi::FromInt(proxy->VariableFeedbackSlot())); | 4414 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 4415 } | 4415 } |
| 4416 // Use a regular load, not a contextual load, to avoid a reference | 4416 // Use a regular load, not a contextual load, to avoid a reference |
| 4417 // error. | 4417 // error. |
| 4418 CallLoadIC(NOT_CONTEXTUAL); | 4418 CallLoadIC(NOT_CONTEXTUAL); |
| 4419 PrepareForBailout(expr, TOS_REG); | 4419 PrepareForBailout(expr, TOS_REG); |
| 4420 context()->Plug(rax); | 4420 context()->Plug(rax); |
| 4421 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4421 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4422 Comment cmnt(masm_, "[ Lookup slot"); | 4422 Comment cmnt(masm_, "[ Lookup slot"); |
| 4423 Label done, slow; | 4423 Label done, slow; |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4836 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4836 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4837 Assembler::target_address_at(call_target_address, | 4837 Assembler::target_address_at(call_target_address, |
| 4838 unoptimized_code)); | 4838 unoptimized_code)); |
| 4839 return OSR_AFTER_STACK_CHECK; | 4839 return OSR_AFTER_STACK_CHECK; |
| 4840 } | 4840 } |
| 4841 | 4841 |
| 4842 | 4842 |
| 4843 } } // namespace v8::internal | 4843 } } // namespace v8::internal |
| 4844 | 4844 |
| 4845 #endif // V8_TARGET_ARCH_X64 | 4845 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |