| 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_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 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 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 context()->Plug(r0); | 1348 context()->Plug(r0); |
| 1349 } | 1349 } |
| 1350 | 1350 |
| 1351 | 1351 |
| 1352 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1352 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1353 Comment cmnt(masm_, "[ VariableProxy"); | 1353 Comment cmnt(masm_, "[ VariableProxy"); |
| 1354 EmitVariableLoad(expr); | 1354 EmitVariableLoad(expr); |
| 1355 } | 1355 } |
| 1356 | 1356 |
| 1357 | 1357 |
| 1358 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, | 1358 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1359 TypeofState typeof_state, | 1359 TypeofState typeof_state, |
| 1360 Label* slow) { | 1360 Label* slow) { |
| 1361 Register current = cp; | 1361 Register current = cp; |
| 1362 Register next = r1; | 1362 Register next = r1; |
| 1363 Register temp = r2; | 1363 Register temp = r2; |
| 1364 | 1364 |
| 1365 Scope* s = scope(); | 1365 Scope* s = scope(); |
| 1366 while (s != NULL) { | 1366 while (s != NULL) { |
| 1367 if (s->num_heap_slots() > 0) { | 1367 if (s->num_heap_slots() > 0) { |
| 1368 if (s->calls_sloppy_eval()) { | 1368 if (s->calls_sloppy_eval()) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1397 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1397 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
| 1398 __ tst(temp, temp); | 1398 __ tst(temp, temp); |
| 1399 __ b(ne, slow); | 1399 __ b(ne, slow); |
| 1400 // Load next context in chain. | 1400 // Load next context in chain. |
| 1401 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1401 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
| 1402 __ b(&loop); | 1402 __ b(&loop); |
| 1403 __ bind(&fast); | 1403 __ bind(&fast); |
| 1404 } | 1404 } |
| 1405 | 1405 |
| 1406 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 1406 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
| 1407 __ mov(LoadIC::NameRegister(), Operand(var->name())); | 1407 __ mov(LoadIC::NameRegister(), Operand(proxy->var()->name())); |
| 1408 if (FLAG_vector_ics) { |
| 1409 __ mov(LoadIC::SlotRegister(), |
| 1410 Operand(Smi::FromInt(proxy->VariableFeedbackSlot()))); |
| 1411 } |
| 1412 |
| 1408 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | 1413 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1409 ? NOT_CONTEXTUAL | 1414 ? NOT_CONTEXTUAL |
| 1410 : CONTEXTUAL; | 1415 : CONTEXTUAL; |
| 1411 CallLoadIC(mode); | 1416 CallLoadIC(mode); |
| 1412 } | 1417 } |
| 1413 | 1418 |
| 1414 | 1419 |
| 1415 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1420 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1416 Label* slow) { | 1421 Label* slow) { |
| 1417 ASSERT(var->IsContextSlot()); | 1422 ASSERT(var->IsContextSlot()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1437 __ tst(temp, temp); | 1442 __ tst(temp, temp); |
| 1438 __ b(ne, slow); | 1443 __ b(ne, slow); |
| 1439 | 1444 |
| 1440 // This function is used only for loads, not stores, so it's safe to | 1445 // This function is used only for loads, not stores, so it's safe to |
| 1441 // return an cp-based operand (the write barrier cannot be allowed to | 1446 // return an cp-based operand (the write barrier cannot be allowed to |
| 1442 // destroy the cp register). | 1447 // destroy the cp register). |
| 1443 return ContextOperand(context, var->index()); | 1448 return ContextOperand(context, var->index()); |
| 1444 } | 1449 } |
| 1445 | 1450 |
| 1446 | 1451 |
| 1447 void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var, | 1452 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, |
| 1448 TypeofState typeof_state, | 1453 TypeofState typeof_state, |
| 1449 Label* slow, | 1454 Label* slow, |
| 1450 Label* done) { | 1455 Label* done) { |
| 1451 // Generate fast-case code for variables that might be shadowed by | 1456 // Generate fast-case code for variables that might be shadowed by |
| 1452 // eval-introduced variables. Eval is used a lot without | 1457 // eval-introduced variables. Eval is used a lot without |
| 1453 // introducing variables. In those cases, we do not want to | 1458 // introducing variables. In those cases, we do not want to |
| 1454 // perform a runtime call for all variables in the scope | 1459 // perform a runtime call for all variables in the scope |
| 1455 // containing the eval. | 1460 // containing the eval. |
| 1461 Variable* var = proxy->var(); |
| 1456 if (var->mode() == DYNAMIC_GLOBAL) { | 1462 if (var->mode() == DYNAMIC_GLOBAL) { |
| 1457 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); | 1463 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); |
| 1458 __ jmp(done); | 1464 __ jmp(done); |
| 1459 } else if (var->mode() == DYNAMIC_LOCAL) { | 1465 } else if (var->mode() == DYNAMIC_LOCAL) { |
| 1460 Variable* local = var->local_if_not_shadowed(); | 1466 Variable* local = var->local_if_not_shadowed(); |
| 1461 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); | 1467 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); |
| 1462 if (local->mode() == LET || local->mode() == CONST || | 1468 if (local->mode() == LET || local->mode() == CONST || |
| 1463 local->mode() == CONST_LEGACY) { | 1469 local->mode() == CONST_LEGACY) { |
| 1464 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); | 1470 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); |
| 1465 if (local->mode() == CONST_LEGACY) { | 1471 if (local->mode() == CONST_LEGACY) { |
| 1466 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); | 1472 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
| 1467 } else { // LET || CONST | 1473 } else { // LET || CONST |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1481 SetSourcePosition(proxy->position()); | 1487 SetSourcePosition(proxy->position()); |
| 1482 Variable* var = proxy->var(); | 1488 Variable* var = proxy->var(); |
| 1483 | 1489 |
| 1484 // Three cases: global variables, lookup variables, and all other types of | 1490 // Three cases: global variables, lookup variables, and all other types of |
| 1485 // variables. | 1491 // variables. |
| 1486 switch (var->location()) { | 1492 switch (var->location()) { |
| 1487 case Variable::UNALLOCATED: { | 1493 case Variable::UNALLOCATED: { |
| 1488 Comment cmnt(masm_, "[ Global variable"); | 1494 Comment cmnt(masm_, "[ Global variable"); |
| 1489 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 1495 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
| 1490 __ mov(LoadIC::NameRegister(), Operand(var->name())); | 1496 __ mov(LoadIC::NameRegister(), Operand(var->name())); |
| 1497 if (FLAG_vector_ics) { |
| 1498 __ mov(LoadIC::SlotRegister(), |
| 1499 Operand(Smi::FromInt(proxy->VariableFeedbackSlot()))); |
| 1500 } |
| 1491 CallLoadIC(CONTEXTUAL); | 1501 CallLoadIC(CONTEXTUAL); |
| 1492 context()->Plug(r0); | 1502 context()->Plug(r0); |
| 1493 break; | 1503 break; |
| 1494 } | 1504 } |
| 1495 | 1505 |
| 1496 case Variable::PARAMETER: | 1506 case Variable::PARAMETER: |
| 1497 case Variable::LOCAL: | 1507 case Variable::LOCAL: |
| 1498 case Variable::CONTEXT: { | 1508 case Variable::CONTEXT: { |
| 1499 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1509 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
| 1500 : "[ Stack variable"); | 1510 : "[ Stack variable"); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1557 } | 1567 } |
| 1558 context()->Plug(var); | 1568 context()->Plug(var); |
| 1559 break; | 1569 break; |
| 1560 } | 1570 } |
| 1561 | 1571 |
| 1562 case Variable::LOOKUP: { | 1572 case Variable::LOOKUP: { |
| 1563 Comment cmnt(masm_, "[ Lookup variable"); | 1573 Comment cmnt(masm_, "[ Lookup variable"); |
| 1564 Label done, slow; | 1574 Label done, slow; |
| 1565 // Generate code for loading from variables potentially shadowed | 1575 // Generate code for loading from variables potentially shadowed |
| 1566 // by eval-introduced variables. | 1576 // by eval-introduced variables. |
| 1567 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); | 1577 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1568 __ bind(&slow); | 1578 __ bind(&slow); |
| 1569 __ mov(r1, Operand(var->name())); | 1579 __ mov(r1, Operand(var->name())); |
| 1570 __ Push(cp, r1); // Context and name. | 1580 __ Push(cp, r1); // Context and name. |
| 1571 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 1581 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 1572 __ bind(&done); | 1582 __ bind(&done); |
| 1573 context()->Plug(r0); | 1583 context()->Plug(r0); |
| 1574 } | 1584 } |
| 1575 } | 1585 } |
| 1576 } | 1586 } |
| 1577 | 1587 |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2071 __ bind(&l_next); | 2081 __ bind(&l_next); |
| 2072 | 2082 |
| 2073 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" | 2083 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" |
| 2074 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter | 2084 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter |
| 2075 __ Push(load_name, r3, r0); // "next", iter, received | 2085 __ Push(load_name, r3, r0); // "next", iter, received |
| 2076 | 2086 |
| 2077 // result = receiver[f](arg); | 2087 // result = receiver[f](arg); |
| 2078 __ bind(&l_call); | 2088 __ bind(&l_call); |
| 2079 __ ldr(load_receiver, MemOperand(sp, kPointerSize)); | 2089 __ ldr(load_receiver, MemOperand(sp, kPointerSize)); |
| 2080 __ ldr(load_name, MemOperand(sp, 2 * kPointerSize)); | 2090 __ ldr(load_name, MemOperand(sp, 2 * kPointerSize)); |
| 2091 if (FLAG_vector_ics) { |
| 2092 __ mov(LoadIC::SlotRegister(), |
| 2093 Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); |
| 2094 } |
| 2081 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2095 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2082 CallIC(ic, TypeFeedbackId::None()); | 2096 CallIC(ic, TypeFeedbackId::None()); |
| 2083 __ mov(r1, r0); | 2097 __ mov(r1, r0); |
| 2084 __ str(r1, MemOperand(sp, 2 * kPointerSize)); | 2098 __ str(r1, MemOperand(sp, 2 * kPointerSize)); |
| 2085 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2099 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
| 2086 __ CallStub(&stub); | 2100 __ CallStub(&stub); |
| 2087 | 2101 |
| 2088 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2102 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2089 __ Drop(1); // The function is still on the stack; drop it. | 2103 __ Drop(1); // The function is still on the stack; drop it. |
| 2090 | 2104 |
| 2091 // if (!result.done) goto l_try; | 2105 // if (!result.done) goto l_try; |
| 2092 __ bind(&l_loop); | 2106 __ bind(&l_loop); |
| 2093 __ Move(load_receiver, r0); | 2107 __ Move(load_receiver, r0); |
| 2094 | 2108 |
| 2095 __ push(load_receiver); // save result | 2109 __ push(load_receiver); // save result |
| 2096 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 2110 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
| 2111 if (FLAG_vector_ics) { |
| 2112 __ mov(LoadIC::SlotRegister(), |
| 2113 Operand(Smi::FromInt(expr->DoneFeedbackSlot()))); |
| 2114 } |
| 2097 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done | 2115 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done |
| 2098 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2116 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2099 CallIC(bool_ic); | 2117 CallIC(bool_ic); |
| 2100 __ cmp(r0, Operand(0)); | 2118 __ cmp(r0, Operand(0)); |
| 2101 __ b(eq, &l_try); | 2119 __ b(eq, &l_try); |
| 2102 | 2120 |
| 2103 // result.value | 2121 // result.value |
| 2104 __ pop(load_receiver); // result | 2122 __ pop(load_receiver); // result |
| 2105 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" | 2123 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
| 2124 if (FLAG_vector_ics) { |
| 2125 __ mov(LoadIC::SlotRegister(), |
| 2126 Operand(Smi::FromInt(expr->ValueFeedbackSlot()))); |
| 2127 } |
| 2106 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value | 2128 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value |
| 2107 context()->DropAndPlug(2, r0); // drop iter and g | 2129 context()->DropAndPlug(2, r0); // drop iter and g |
| 2108 break; | 2130 break; |
| 2109 } | 2131 } |
| 2110 } | 2132 } |
| 2111 } | 2133 } |
| 2112 | 2134 |
| 2113 | 2135 |
| 2114 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2136 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2115 Expression *value, | 2137 Expression *value, |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2271 // root set. | 2293 // root set. |
| 2272 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, | 2294 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, |
| 2273 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); | 2295 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2274 } | 2296 } |
| 2275 | 2297 |
| 2276 | 2298 |
| 2277 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2299 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2278 SetSourcePosition(prop->position()); | 2300 SetSourcePosition(prop->position()); |
| 2279 Literal* key = prop->key()->AsLiteral(); | 2301 Literal* key = prop->key()->AsLiteral(); |
| 2280 __ mov(LoadIC::NameRegister(), Operand(key->value())); | 2302 __ mov(LoadIC::NameRegister(), Operand(key->value())); |
| 2281 // Call load IC. It has register arguments receiver and property. | 2303 if (FLAG_vector_ics) { |
| 2282 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2304 __ mov(LoadIC::SlotRegister(), |
| 2305 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
| 2306 CallLoadIC(NOT_CONTEXTUAL); |
| 2307 } else { |
| 2308 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2309 } |
| 2283 } | 2310 } |
| 2284 | 2311 |
| 2285 | 2312 |
| 2286 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2313 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2287 SetSourcePosition(prop->position()); | 2314 SetSourcePosition(prop->position()); |
| 2288 // Call keyed load IC. It has register arguments receiver and key. | |
| 2289 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2315 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2290 CallIC(ic, prop->PropertyFeedbackId()); | 2316 if (FLAG_vector_ics) { |
| 2317 __ mov(LoadIC::SlotRegister(), |
| 2318 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
| 2319 CallIC(ic); |
| 2320 } else { |
| 2321 CallIC(ic, prop->PropertyFeedbackId()); |
| 2322 } |
| 2291 } | 2323 } |
| 2292 | 2324 |
| 2293 | 2325 |
| 2294 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2326 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2295 Token::Value op, | 2327 Token::Value op, |
| 2296 OverwriteMode mode, | 2328 OverwriteMode mode, |
| 2297 Expression* left_expr, | 2329 Expression* left_expr, |
| 2298 Expression* right_expr) { | 2330 Expression* right_expr) { |
| 2299 Label done, smi_case, stub_call; | 2331 Label done, smi_case, stub_call; |
| 2300 | 2332 |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2754 EmitCallWithLoadIC(expr); | 2786 EmitCallWithLoadIC(expr); |
| 2755 | 2787 |
| 2756 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2788 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
| 2757 // Call to a lookup slot (dynamically introduced variable). | 2789 // Call to a lookup slot (dynamically introduced variable). |
| 2758 VariableProxy* proxy = callee->AsVariableProxy(); | 2790 VariableProxy* proxy = callee->AsVariableProxy(); |
| 2759 Label slow, done; | 2791 Label slow, done; |
| 2760 | 2792 |
| 2761 { PreservePositionScope scope(masm()->positions_recorder()); | 2793 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2762 // Generate code for loading from variables potentially shadowed | 2794 // Generate code for loading from variables potentially shadowed |
| 2763 // by eval-introduced variables. | 2795 // by eval-introduced variables. |
| 2764 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2796 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
| 2765 } | 2797 } |
| 2766 | 2798 |
| 2767 __ bind(&slow); | 2799 __ bind(&slow); |
| 2768 // Call the runtime to find the function to call (returned in r0) | 2800 // Call the runtime to find the function to call (returned in r0) |
| 2769 // and the object holding it (returned in edx). | 2801 // and the object holding it (returned in edx). |
| 2770 ASSERT(!context_register().is(r2)); | 2802 ASSERT(!context_register().is(r2)); |
| 2771 __ mov(r2, Operand(proxy->name())); | 2803 __ mov(r2, Operand(proxy->name())); |
| 2772 __ Push(context_register(), r2); | 2804 __ Push(context_register(), r2); |
| 2773 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 2805 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 2774 __ Push(r0, r1); // Function, receiver. | 2806 __ Push(r0, r1); // Function, receiver. |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4049 | 4081 |
| 4050 if (expr->is_jsruntime()) { | 4082 if (expr->is_jsruntime()) { |
| 4051 // Push the builtins object as the receiver. | 4083 // Push the builtins object as the receiver. |
| 4052 Register receiver = LoadIC::ReceiverRegister(); | 4084 Register receiver = LoadIC::ReceiverRegister(); |
| 4053 __ ldr(receiver, GlobalObjectOperand()); | 4085 __ ldr(receiver, GlobalObjectOperand()); |
| 4054 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); | 4086 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); |
| 4055 __ push(receiver); | 4087 __ push(receiver); |
| 4056 | 4088 |
| 4057 // Load the function from the receiver. | 4089 // Load the function from the receiver. |
| 4058 __ mov(LoadIC::NameRegister(), Operand(expr->name())); | 4090 __ mov(LoadIC::NameRegister(), Operand(expr->name())); |
| 4059 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4091 if (FLAG_vector_ics) { |
| 4092 __ mov(LoadIC::SlotRegister(), |
| 4093 Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot()))); |
| 4094 CallLoadIC(NOT_CONTEXTUAL); |
| 4095 } else { |
| 4096 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4097 } |
| 4060 | 4098 |
| 4061 // Push the target function under the receiver. | 4099 // Push the target function under the receiver. |
| 4062 __ ldr(ip, MemOperand(sp, 0)); | 4100 __ ldr(ip, MemOperand(sp, 0)); |
| 4063 __ push(ip); | 4101 __ push(ip); |
| 4064 __ str(r0, MemOperand(sp, kPointerSize)); | 4102 __ str(r0, MemOperand(sp, kPointerSize)); |
| 4065 | 4103 |
| 4066 // Push the arguments ("left-to-right"). | 4104 // Push the arguments ("left-to-right"). |
| 4067 int arg_count = args->length(); | 4105 int arg_count = args->length(); |
| 4068 for (int i = 0; i < arg_count; i++) { | 4106 for (int i = 0; i < arg_count; i++) { |
| 4069 VisitForStackValue(args->at(i)); | 4107 VisitForStackValue(args->at(i)); |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4383 | 4421 |
| 4384 | 4422 |
| 4385 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4423 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4386 ASSERT(!context()->IsEffect()); | 4424 ASSERT(!context()->IsEffect()); |
| 4387 ASSERT(!context()->IsTest()); | 4425 ASSERT(!context()->IsTest()); |
| 4388 VariableProxy* proxy = expr->AsVariableProxy(); | 4426 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4389 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4427 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4390 Comment cmnt(masm_, "[ Global variable"); | 4428 Comment cmnt(masm_, "[ Global variable"); |
| 4391 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 4429 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
| 4392 __ mov(LoadIC::NameRegister(), Operand(proxy->name())); | 4430 __ mov(LoadIC::NameRegister(), Operand(proxy->name())); |
| 4431 if (FLAG_vector_ics) { |
| 4432 __ mov(LoadIC::SlotRegister(), |
| 4433 Operand(Smi::FromInt(proxy->VariableFeedbackSlot()))); |
| 4434 } |
| 4393 // Use a regular load, not a contextual load, to avoid a reference | 4435 // Use a regular load, not a contextual load, to avoid a reference |
| 4394 // error. | 4436 // error. |
| 4395 CallLoadIC(NOT_CONTEXTUAL); | 4437 CallLoadIC(NOT_CONTEXTUAL); |
| 4396 PrepareForBailout(expr, TOS_REG); | 4438 PrepareForBailout(expr, TOS_REG); |
| 4397 context()->Plug(r0); | 4439 context()->Plug(r0); |
| 4398 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4440 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4399 Comment cmnt(masm_, "[ Lookup slot"); | 4441 Comment cmnt(masm_, "[ Lookup slot"); |
| 4400 Label done, slow; | 4442 Label done, slow; |
| 4401 | 4443 |
| 4402 // Generate code for loading from variables potentially shadowed | 4444 // Generate code for loading from variables potentially shadowed |
| 4403 // by eval-introduced variables. | 4445 // by eval-introduced variables. |
| 4404 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4446 EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done); |
| 4405 | 4447 |
| 4406 __ bind(&slow); | 4448 __ bind(&slow); |
| 4407 __ mov(r0, Operand(proxy->name())); | 4449 __ mov(r0, Operand(proxy->name())); |
| 4408 __ Push(cp, r0); | 4450 __ Push(cp, r0); |
| 4409 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); | 4451 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); |
| 4410 PrepareForBailout(expr, TOS_REG); | 4452 PrepareForBailout(expr, TOS_REG); |
| 4411 __ bind(&done); | 4453 __ bind(&done); |
| 4412 | 4454 |
| 4413 context()->Plug(r0); | 4455 context()->Plug(r0); |
| 4414 } else { | 4456 } else { |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4848 | 4890 |
| 4849 ASSERT(interrupt_address == | 4891 ASSERT(interrupt_address == |
| 4850 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4892 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 4851 return OSR_AFTER_STACK_CHECK; | 4893 return OSR_AFTER_STACK_CHECK; |
| 4852 } | 4894 } |
| 4853 | 4895 |
| 4854 | 4896 |
| 4855 } } // namespace v8::internal | 4897 } } // namespace v8::internal |
| 4856 | 4898 |
| 4857 #endif // V8_TARGET_ARCH_ARM | 4899 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |