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 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 context()->Plug(rax); | 1314 context()->Plug(rax); |
1315 } | 1315 } |
1316 | 1316 |
1317 | 1317 |
1318 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1318 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
1319 Comment cmnt(masm_, "[ VariableProxy"); | 1319 Comment cmnt(masm_, "[ VariableProxy"); |
1320 EmitVariableLoad(expr); | 1320 EmitVariableLoad(expr); |
1321 } | 1321 } |
1322 | 1322 |
1323 | 1323 |
1324 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, | 1324 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1325 TypeofState typeof_state, | 1325 TypeofState typeof_state, |
1326 Label* slow) { | 1326 Label* slow) { |
1327 Register context = rsi; | 1327 Register context = rsi; |
1328 Register temp = rdx; | 1328 Register temp = rdx; |
1329 | 1329 |
1330 Scope* s = scope(); | 1330 Scope* s = scope(); |
1331 while (s != NULL) { | 1331 while (s != NULL) { |
1332 if (s->num_heap_slots() > 0) { | 1332 if (s->num_heap_slots() > 0) { |
1333 if (s->calls_sloppy_eval()) { | 1333 if (s->calls_sloppy_eval()) { |
1334 // Check that extension is NULL. | 1334 // Check that extension is NULL. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 __ j(not_equal, slow); | 1366 __ j(not_equal, slow); |
1367 // Load next context in chain. | 1367 // Load next context in chain. |
1368 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1368 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
1369 __ jmp(&next); | 1369 __ jmp(&next); |
1370 __ bind(&fast); | 1370 __ bind(&fast); |
1371 } | 1371 } |
1372 | 1372 |
1373 // All extension objects were empty and it is safe to use a global | 1373 // All extension objects were empty and it is safe to use a global |
1374 // load IC call. | 1374 // load IC call. |
1375 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 1375 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
1376 __ Move(LoadIC::NameRegister(), var->name()); | 1376 __ Move(LoadIC::NameRegister(), proxy->var()->name()); |
| 1377 if (FLAG_vector_ics) { |
| 1378 __ Move(LoadIC::SlotRegister(), |
| 1379 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 1380 } |
| 1381 |
1377 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | 1382 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
1378 ? NOT_CONTEXTUAL | 1383 ? NOT_CONTEXTUAL |
1379 : CONTEXTUAL; | 1384 : CONTEXTUAL; |
1380 CallLoadIC(mode); | 1385 CallLoadIC(mode); |
1381 } | 1386 } |
1382 | 1387 |
1383 | 1388 |
1384 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1389 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1385 Label* slow) { | 1390 Label* slow) { |
1386 ASSERT(var->IsContextSlot()); | 1391 ASSERT(var->IsContextSlot()); |
(...skipping 17 matching lines...) Expand all Loading... |
1404 __ cmpp(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0)); | 1409 __ cmpp(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0)); |
1405 __ j(not_equal, slow); | 1410 __ j(not_equal, slow); |
1406 | 1411 |
1407 // This function is used only for loads, not stores, so it's safe to | 1412 // This function is used only for loads, not stores, so it's safe to |
1408 // return an rsi-based operand (the write barrier cannot be allowed to | 1413 // return an rsi-based operand (the write barrier cannot be allowed to |
1409 // destroy the rsi register). | 1414 // destroy the rsi register). |
1410 return ContextOperand(context, var->index()); | 1415 return ContextOperand(context, var->index()); |
1411 } | 1416 } |
1412 | 1417 |
1413 | 1418 |
1414 void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var, | 1419 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, |
1415 TypeofState typeof_state, | 1420 TypeofState typeof_state, |
1416 Label* slow, | 1421 Label* slow, |
1417 Label* done) { | 1422 Label* done) { |
1418 // Generate fast-case code for variables that might be shadowed by | 1423 // Generate fast-case code for variables that might be shadowed by |
1419 // eval-introduced variables. Eval is used a lot without | 1424 // eval-introduced variables. Eval is used a lot without |
1420 // introducing variables. In those cases, we do not want to | 1425 // introducing variables. In those cases, we do not want to |
1421 // perform a runtime call for all variables in the scope | 1426 // perform a runtime call for all variables in the scope |
1422 // containing the eval. | 1427 // containing the eval. |
| 1428 Variable* var = proxy->var(); |
1423 if (var->mode() == DYNAMIC_GLOBAL) { | 1429 if (var->mode() == DYNAMIC_GLOBAL) { |
1424 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); | 1430 EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); |
1425 __ jmp(done); | 1431 __ jmp(done); |
1426 } else if (var->mode() == DYNAMIC_LOCAL) { | 1432 } else if (var->mode() == DYNAMIC_LOCAL) { |
1427 Variable* local = var->local_if_not_shadowed(); | 1433 Variable* local = var->local_if_not_shadowed(); |
1428 __ movp(rax, ContextSlotOperandCheckExtensions(local, slow)); | 1434 __ movp(rax, ContextSlotOperandCheckExtensions(local, slow)); |
1429 if (local->mode() == LET || local->mode() == CONST || | 1435 if (local->mode() == LET || local->mode() == CONST || |
1430 local->mode() == CONST_LEGACY) { | 1436 local->mode() == CONST_LEGACY) { |
1431 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); | 1437 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
1432 __ j(not_equal, done); | 1438 __ j(not_equal, done); |
1433 if (local->mode() == CONST_LEGACY) { | 1439 if (local->mode() == CONST_LEGACY) { |
1434 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 1440 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
(...skipping 12 matching lines...) Expand all Loading... |
1447 SetSourcePosition(proxy->position()); | 1453 SetSourcePosition(proxy->position()); |
1448 Variable* var = proxy->var(); | 1454 Variable* var = proxy->var(); |
1449 | 1455 |
1450 // Three cases: global variables, lookup variables, and all other types of | 1456 // Three cases: global variables, lookup variables, and all other types of |
1451 // variables. | 1457 // variables. |
1452 switch (var->location()) { | 1458 switch (var->location()) { |
1453 case Variable::UNALLOCATED: { | 1459 case Variable::UNALLOCATED: { |
1454 Comment cmnt(masm_, "[ Global variable"); | 1460 Comment cmnt(masm_, "[ Global variable"); |
1455 __ Move(LoadIC::NameRegister(), var->name()); | 1461 __ Move(LoadIC::NameRegister(), var->name()); |
1456 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 1462 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
| 1463 if (FLAG_vector_ics) { |
| 1464 __ Move(LoadIC::SlotRegister(), |
| 1465 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 1466 } |
1457 CallLoadIC(CONTEXTUAL); | 1467 CallLoadIC(CONTEXTUAL); |
1458 context()->Plug(rax); | 1468 context()->Plug(rax); |
1459 break; | 1469 break; |
1460 } | 1470 } |
1461 | 1471 |
1462 case Variable::PARAMETER: | 1472 case Variable::PARAMETER: |
1463 case Variable::LOCAL: | 1473 case Variable::LOCAL: |
1464 case Variable::CONTEXT: { | 1474 case Variable::CONTEXT: { |
1465 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" | 1475 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" |
1466 : "[ Stack slot"); | 1476 : "[ Stack slot"); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1522 } | 1532 } |
1523 context()->Plug(var); | 1533 context()->Plug(var); |
1524 break; | 1534 break; |
1525 } | 1535 } |
1526 | 1536 |
1527 case Variable::LOOKUP: { | 1537 case Variable::LOOKUP: { |
1528 Comment cmnt(masm_, "[ Lookup slot"); | 1538 Comment cmnt(masm_, "[ Lookup slot"); |
1529 Label done, slow; | 1539 Label done, slow; |
1530 // Generate code for loading from variables potentially shadowed | 1540 // Generate code for loading from variables potentially shadowed |
1531 // by eval-introduced variables. | 1541 // by eval-introduced variables. |
1532 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); | 1542 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
1533 __ bind(&slow); | 1543 __ bind(&slow); |
1534 __ Push(rsi); // Context. | 1544 __ Push(rsi); // Context. |
1535 __ Push(var->name()); | 1545 __ Push(var->name()); |
1536 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 1546 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
1537 __ bind(&done); | 1547 __ bind(&done); |
1538 context()->Plug(rax); | 1548 context()->Plug(rax); |
1539 break; | 1549 break; |
1540 } | 1550 } |
1541 } | 1551 } |
1542 } | 1552 } |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2048 __ bind(&l_next); | 2058 __ bind(&l_next); |
2049 | 2059 |
2050 __ LoadRoot(load_name, Heap::knext_stringRootIndex); | 2060 __ LoadRoot(load_name, Heap::knext_stringRootIndex); |
2051 __ Push(load_name); // "next" | 2061 __ Push(load_name); // "next" |
2052 __ Push(Operand(rsp, 2 * kPointerSize)); // iter | 2062 __ Push(Operand(rsp, 2 * kPointerSize)); // iter |
2053 __ Push(rax); // received | 2063 __ Push(rax); // received |
2054 | 2064 |
2055 // result = receiver[f](arg); | 2065 // result = receiver[f](arg); |
2056 __ bind(&l_call); | 2066 __ bind(&l_call); |
2057 __ movp(load_receiver, Operand(rsp, kPointerSize)); | 2067 __ movp(load_receiver, Operand(rsp, kPointerSize)); |
| 2068 if (FLAG_vector_ics) { |
| 2069 __ Move(LoadIC::SlotRegister(), |
| 2070 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); |
| 2071 } |
2058 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2072 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2059 CallIC(ic, TypeFeedbackId::None()); | 2073 CallIC(ic, TypeFeedbackId::None()); |
2060 __ movp(rdi, rax); | 2074 __ movp(rdi, rax); |
2061 __ movp(Operand(rsp, 2 * kPointerSize), rdi); | 2075 __ movp(Operand(rsp, 2 * kPointerSize), rdi); |
2062 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2076 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2063 __ CallStub(&stub); | 2077 __ CallStub(&stub); |
2064 | 2078 |
2065 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2079 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2066 __ Drop(1); // The function is still on the stack; drop it. | 2080 __ Drop(1); // The function is still on the stack; drop it. |
2067 | 2081 |
2068 // if (!result.done) goto l_try; | 2082 // if (!result.done) goto l_try; |
2069 __ bind(&l_loop); | 2083 __ bind(&l_loop); |
2070 __ Move(load_receiver, rax); | 2084 __ Move(load_receiver, rax); |
2071 __ Push(load_receiver); // save result | 2085 __ Push(load_receiver); // save result |
2072 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" | 2086 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
| 2087 if (FLAG_vector_ics) { |
| 2088 __ Move(LoadIC::SlotRegister(), Smi::FromInt(expr->DoneFeedbackSlot())); |
| 2089 } |
2073 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done | 2090 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done |
2074 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2091 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2075 CallIC(bool_ic); | 2092 CallIC(bool_ic); |
2076 __ testp(result_register(), result_register()); | 2093 __ testp(result_register(), result_register()); |
2077 __ j(zero, &l_try); | 2094 __ j(zero, &l_try); |
2078 | 2095 |
2079 // result.value | 2096 // result.value |
2080 __ Pop(load_receiver); // result | 2097 __ Pop(load_receiver); // result |
2081 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" | 2098 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
| 2099 if (FLAG_vector_ics) { |
| 2100 __ Move(LoadIC::SlotRegister(), |
| 2101 Smi::FromInt(expr->ValueFeedbackSlot())); |
| 2102 } |
2082 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax | 2103 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax |
2083 context()->DropAndPlug(2, rax); // drop iter and g | 2104 context()->DropAndPlug(2, rax); // drop iter and g |
2084 break; | 2105 break; |
2085 } | 2106 } |
2086 } | 2107 } |
2087 } | 2108 } |
2088 | 2109 |
2089 | 2110 |
2090 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2111 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2091 Expression *value, | 2112 Expression *value, |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2233 // root set. | 2254 // root set. |
2234 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, | 2255 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, |
2235 rcx, rdx, kDontSaveFPRegs); | 2256 rcx, rdx, kDontSaveFPRegs); |
2236 } | 2257 } |
2237 | 2258 |
2238 | 2259 |
2239 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2260 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2240 SetSourcePosition(prop->position()); | 2261 SetSourcePosition(prop->position()); |
2241 Literal* key = prop->key()->AsLiteral(); | 2262 Literal* key = prop->key()->AsLiteral(); |
2242 __ Move(LoadIC::NameRegister(), key->value()); | 2263 __ Move(LoadIC::NameRegister(), key->value()); |
2243 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2264 if (FLAG_vector_ics) { |
| 2265 __ Move(LoadIC::SlotRegister(), Smi::FromInt(prop->PropertyFeedbackSlot())); |
| 2266 CallLoadIC(NOT_CONTEXTUAL); |
| 2267 } else { |
| 2268 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2269 } |
2244 } | 2270 } |
2245 | 2271 |
2246 | 2272 |
2247 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2273 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2248 SetSourcePosition(prop->position()); | 2274 SetSourcePosition(prop->position()); |
2249 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2275 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2250 CallIC(ic, prop->PropertyFeedbackId()); | 2276 if (FLAG_vector_ics) { |
| 2277 __ Move(LoadIC::SlotRegister(), Smi::FromInt(prop->PropertyFeedbackSlot())); |
| 2278 CallIC(ic); |
| 2279 } else { |
| 2280 CallIC(ic, prop->PropertyFeedbackId()); |
| 2281 } |
2251 } | 2282 } |
2252 | 2283 |
2253 | 2284 |
2254 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2285 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2255 Token::Value op, | 2286 Token::Value op, |
2256 OverwriteMode mode, | 2287 OverwriteMode mode, |
2257 Expression* left, | 2288 Expression* left, |
2258 Expression* right) { | 2289 Expression* right) { |
2259 // Do combined smi check of the operands. Left operand is on the | 2290 // Do combined smi check of the operands. Left operand is on the |
2260 // stack (popped into rdx). Right operand is in rax but moved into | 2291 // stack (popped into rdx). Right operand is in rax but moved into |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2669 EmitCallWithLoadIC(expr); | 2700 EmitCallWithLoadIC(expr); |
2670 | 2701 |
2671 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2702 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
2672 // Call to a lookup slot (dynamically introduced variable). | 2703 // Call to a lookup slot (dynamically introduced variable). |
2673 VariableProxy* proxy = callee->AsVariableProxy(); | 2704 VariableProxy* proxy = callee->AsVariableProxy(); |
2674 Label slow, done; | 2705 Label slow, done; |
2675 | 2706 |
2676 { PreservePositionScope scope(masm()->positions_recorder()); | 2707 { PreservePositionScope scope(masm()->positions_recorder()); |
2677 // Generate code for loading from variables potentially shadowed by | 2708 // Generate code for loading from variables potentially shadowed by |
2678 // eval-introduced variables. | 2709 // eval-introduced variables. |
2679 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2710 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
2680 } | 2711 } |
2681 __ bind(&slow); | 2712 __ bind(&slow); |
2682 // Call the runtime to find the function to call (returned in rax) and | 2713 // Call the runtime to find the function to call (returned in rax) and |
2683 // the object holding it (returned in rdx). | 2714 // the object holding it (returned in rdx). |
2684 __ Push(context_register()); | 2715 __ Push(context_register()); |
2685 __ Push(proxy->name()); | 2716 __ Push(proxy->name()); |
2686 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 2717 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
2687 __ Push(rax); // Function. | 2718 __ Push(rax); // Function. |
2688 __ Push(rdx); // Receiver. | 2719 __ Push(rdx); // Receiver. |
2689 | 2720 |
(...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4029 int arg_count = args->length(); | 4060 int arg_count = args->length(); |
4030 | 4061 |
4031 if (expr->is_jsruntime()) { | 4062 if (expr->is_jsruntime()) { |
4032 // Push the builtins object as receiver. | 4063 // Push the builtins object as receiver. |
4033 __ movp(rax, GlobalObjectOperand()); | 4064 __ movp(rax, GlobalObjectOperand()); |
4034 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 4065 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
4035 | 4066 |
4036 // Load the function from the receiver. | 4067 // Load the function from the receiver. |
4037 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); | 4068 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); |
4038 __ Move(LoadIC::NameRegister(), expr->name()); | 4069 __ Move(LoadIC::NameRegister(), expr->name()); |
4039 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4070 if (FLAG_vector_ics) { |
| 4071 __ Move(LoadIC::SlotRegister(), |
| 4072 Smi::FromInt(expr->CallRuntimeFeedbackSlot())); |
| 4073 CallLoadIC(NOT_CONTEXTUAL); |
| 4074 } else { |
| 4075 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4076 } |
4040 | 4077 |
4041 // Push the target function under the receiver. | 4078 // Push the target function under the receiver. |
4042 __ Push(Operand(rsp, 0)); | 4079 __ Push(Operand(rsp, 0)); |
4043 __ movp(Operand(rsp, kPointerSize), rax); | 4080 __ movp(Operand(rsp, kPointerSize), rax); |
4044 | 4081 |
4045 // Push the arguments ("left-to-right"). | 4082 // Push the arguments ("left-to-right"). |
4046 for (int i = 0; i < arg_count; i++) { | 4083 for (int i = 0; i < arg_count; i++) { |
4047 VisitForStackValue(args->at(i)); | 4084 VisitForStackValue(args->at(i)); |
4048 } | 4085 } |
4049 | 4086 |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4370 | 4407 |
4371 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4408 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4372 VariableProxy* proxy = expr->AsVariableProxy(); | 4409 VariableProxy* proxy = expr->AsVariableProxy(); |
4373 ASSERT(!context()->IsEffect()); | 4410 ASSERT(!context()->IsEffect()); |
4374 ASSERT(!context()->IsTest()); | 4411 ASSERT(!context()->IsTest()); |
4375 | 4412 |
4376 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4413 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4377 Comment cmnt(masm_, "[ Global variable"); | 4414 Comment cmnt(masm_, "[ Global variable"); |
4378 __ Move(LoadIC::NameRegister(), proxy->name()); | 4415 __ Move(LoadIC::NameRegister(), proxy->name()); |
4379 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); | 4416 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
| 4417 if (FLAG_vector_ics) { |
| 4418 __ Move(LoadIC::SlotRegister(), |
| 4419 Smi::FromInt(proxy->VariableFeedbackSlot())); |
| 4420 } |
4380 // Use a regular load, not a contextual load, to avoid a reference | 4421 // Use a regular load, not a contextual load, to avoid a reference |
4381 // error. | 4422 // error. |
4382 CallLoadIC(NOT_CONTEXTUAL); | 4423 CallLoadIC(NOT_CONTEXTUAL); |
4383 PrepareForBailout(expr, TOS_REG); | 4424 PrepareForBailout(expr, TOS_REG); |
4384 context()->Plug(rax); | 4425 context()->Plug(rax); |
4385 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4426 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4386 Comment cmnt(masm_, "[ Lookup slot"); | 4427 Comment cmnt(masm_, "[ Lookup slot"); |
4387 Label done, slow; | 4428 Label done, slow; |
4388 | 4429 |
4389 // Generate code for loading from variables potentially shadowed | 4430 // Generate code for loading from variables potentially shadowed |
4390 // by eval-introduced variables. | 4431 // by eval-introduced variables. |
4391 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4432 EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done); |
4392 | 4433 |
4393 __ bind(&slow); | 4434 __ bind(&slow); |
4394 __ Push(rsi); | 4435 __ Push(rsi); |
4395 __ Push(proxy->name()); | 4436 __ Push(proxy->name()); |
4396 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); | 4437 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); |
4397 PrepareForBailout(expr, TOS_REG); | 4438 PrepareForBailout(expr, TOS_REG); |
4398 __ bind(&done); | 4439 __ bind(&done); |
4399 | 4440 |
4400 context()->Plug(rax); | 4441 context()->Plug(rax); |
4401 } else { | 4442 } else { |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4800 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4841 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4801 Assembler::target_address_at(call_target_address, | 4842 Assembler::target_address_at(call_target_address, |
4802 unoptimized_code)); | 4843 unoptimized_code)); |
4803 return OSR_AFTER_STACK_CHECK; | 4844 return OSR_AFTER_STACK_CHECK; |
4804 } | 4845 } |
4805 | 4846 |
4806 | 4847 |
4807 } } // namespace v8::internal | 4848 } } // namespace v8::internal |
4808 | 4849 |
4809 #endif // V8_TARGET_ARCH_X64 | 4850 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |