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 |