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 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug/debug.h" | 10 #include "src/debug/debug.h" |
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1160 } | 1160 } |
1161 | 1161 |
1162 | 1162 |
1163 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, | 1163 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
1164 FeedbackVectorSlot slot) { | 1164 FeedbackVectorSlot slot) { |
1165 DCHECK(NeedsHomeObject(initializer)); | 1165 DCHECK(NeedsHomeObject(initializer)); |
1166 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1166 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1167 __ mov(StoreDescriptor::NameRegister(), | 1167 __ mov(StoreDescriptor::NameRegister(), |
1168 Immediate(isolate()->factory()->home_object_symbol())); | 1168 Immediate(isolate()->factory()->home_object_symbol())); |
1169 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); | 1169 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); |
1170 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1170 EmitLoadStoreICSlot(slot); |
1171 CallStoreIC(); | 1171 CallStoreIC(); |
1172 } | 1172 } |
1173 | 1173 |
1174 | 1174 |
1175 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, | 1175 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, |
1176 int offset, | 1176 int offset, |
1177 FeedbackVectorSlot slot) { | 1177 FeedbackVectorSlot slot) { |
1178 DCHECK(NeedsHomeObject(initializer)); | 1178 DCHECK(NeedsHomeObject(initializer)); |
1179 __ mov(StoreDescriptor::ReceiverRegister(), eax); | 1179 __ mov(StoreDescriptor::ReceiverRegister(), eax); |
1180 __ mov(StoreDescriptor::NameRegister(), | 1180 __ mov(StoreDescriptor::NameRegister(), |
1181 Immediate(isolate()->factory()->home_object_symbol())); | 1181 Immediate(isolate()->factory()->home_object_symbol())); |
1182 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); | 1182 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); |
1183 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1183 EmitLoadStoreICSlot(slot); |
1184 CallStoreIC(); | 1184 CallStoreIC(); |
1185 } | 1185 } |
1186 | 1186 |
1187 | 1187 |
1188 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1188 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1189 TypeofMode typeof_mode, | 1189 TypeofMode typeof_mode, |
1190 Label* slow) { | 1190 Label* slow) { |
1191 Register context = esi; | 1191 Register context = esi; |
1192 Register temp = edx; | 1192 Register temp = edx; |
1193 | 1193 |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 // Fall through. | 1502 // Fall through. |
1503 case ObjectLiteral::Property::COMPUTED: | 1503 case ObjectLiteral::Property::COMPUTED: |
1504 // It is safe to use [[Put]] here because the boilerplate already | 1504 // It is safe to use [[Put]] here because the boilerplate already |
1505 // contains computed properties with an uninitialized value. | 1505 // contains computed properties with an uninitialized value. |
1506 if (key->value()->IsInternalizedString()) { | 1506 if (key->value()->IsInternalizedString()) { |
1507 if (property->emit_store()) { | 1507 if (property->emit_store()) { |
1508 VisitForAccumulatorValue(value); | 1508 VisitForAccumulatorValue(value); |
1509 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 1509 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
1510 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); | 1510 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); |
1511 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1511 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1512 if (FLAG_vector_stores) { | 1512 EmitLoadStoreICSlot(property->GetSlot(0)); |
1513 EmitLoadStoreICSlot(property->GetSlot(0)); | 1513 CallStoreIC(); |
1514 CallStoreIC(); | |
1515 } else { | |
1516 CallStoreIC(key->LiteralFeedbackId()); | |
1517 } | |
1518 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1514 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1519 if (NeedsHomeObject(value)) { | 1515 if (NeedsHomeObject(value)) { |
1520 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); | 1516 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
1521 } | 1517 } |
1522 } else { | 1518 } else { |
1523 VisitForEffect(value); | 1519 VisitForEffect(value); |
1524 } | 1520 } |
1525 break; | 1521 break; |
1526 } | 1522 } |
1527 __ push(Operand(esp, 0)); // Duplicate receiver. | 1523 __ push(Operand(esp, 0)); // Duplicate receiver. |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 // is already set in the cloned array. | 1688 // is already set in the cloned array. |
1693 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1689 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1694 | 1690 |
1695 if (!result_saved) { | 1691 if (!result_saved) { |
1696 __ push(eax); // array literal. | 1692 __ push(eax); // array literal. |
1697 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1693 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
1698 result_saved = true; | 1694 result_saved = true; |
1699 } | 1695 } |
1700 VisitForAccumulatorValue(subexpr); | 1696 VisitForAccumulatorValue(subexpr); |
1701 | 1697 |
1702 if (FLAG_vector_stores) { | 1698 __ mov(StoreDescriptor::NameRegister(), |
1703 __ mov(StoreDescriptor::NameRegister(), | 1699 Immediate(Smi::FromInt(array_index))); |
1704 Immediate(Smi::FromInt(array_index))); | 1700 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); |
1705 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); | 1701 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); |
1706 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); | 1702 Handle<Code> ic = |
1707 Handle<Code> ic = | 1703 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
1708 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 1704 CallIC(ic); |
1709 CallIC(ic); | |
1710 } else if (has_constant_fast_elements) { | |
1711 // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they | |
1712 // cannot transition and don't need to call the runtime stub. | |
1713 int offset = FixedArray::kHeaderSize + (array_index * kPointerSize); | |
1714 __ mov(ebx, Operand(esp, kPointerSize)); // Copy of array literal. | |
1715 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); | |
1716 // Store the subexpression value in the array's elements. | |
1717 __ mov(FieldOperand(ebx, offset), result_register()); | |
1718 // Update the write barrier for the array store. | |
1719 __ RecordWriteField(ebx, offset, result_register(), ecx, kDontSaveFPRegs, | |
1720 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); | |
1721 } else { | |
1722 // Store the subexpression value in the array's elements. | |
1723 __ mov(ecx, Immediate(Smi::FromInt(array_index))); | |
1724 StoreArrayLiteralElementStub stub(isolate()); | |
1725 __ CallStub(&stub); | |
1726 } | |
1727 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1705 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
1728 } | 1706 } |
1729 | 1707 |
1730 // In case the array literal contains spread expressions it has two parts. The | 1708 // In case the array literal contains spread expressions it has two parts. The |
1731 // first part is the "static" array which has a literal index is handled | 1709 // first part is the "static" array which has a literal index is handled |
1732 // above. The second part is the part after the first spread expression | 1710 // above. The second part is the part after the first spread expression |
1733 // (inclusive) and these elements gets appended to the array. Note that the | 1711 // (inclusive) and these elements gets appended to the array. Note that the |
1734 // number elements an iterable produces is unknown ahead of time. | 1712 // number elements an iterable produces is unknown ahead of time. |
1735 if (array_index < length && result_saved) { | 1713 if (array_index < length && result_saved) { |
1736 __ Drop(1); // literal index | 1714 __ Drop(1); // literal index |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2407 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2385 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2408 break; | 2386 break; |
2409 } | 2387 } |
2410 case NAMED_PROPERTY: { | 2388 case NAMED_PROPERTY: { |
2411 __ push(eax); // Preserve value. | 2389 __ push(eax); // Preserve value. |
2412 VisitForAccumulatorValue(prop->obj()); | 2390 VisitForAccumulatorValue(prop->obj()); |
2413 __ Move(StoreDescriptor::ReceiverRegister(), eax); | 2391 __ Move(StoreDescriptor::ReceiverRegister(), eax); |
2414 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2392 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
2415 __ mov(StoreDescriptor::NameRegister(), | 2393 __ mov(StoreDescriptor::NameRegister(), |
2416 prop->key()->AsLiteral()->value()); | 2394 prop->key()->AsLiteral()->value()); |
2417 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2395 EmitLoadStoreICSlot(slot); |
2418 CallStoreIC(); | 2396 CallStoreIC(); |
2419 break; | 2397 break; |
2420 } | 2398 } |
2421 case NAMED_SUPER_PROPERTY: { | 2399 case NAMED_SUPER_PROPERTY: { |
2422 __ push(eax); | 2400 __ push(eax); |
2423 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2401 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2424 VisitForAccumulatorValue( | 2402 VisitForAccumulatorValue( |
2425 prop->obj()->AsSuperPropertyReference()->home_object()); | 2403 prop->obj()->AsSuperPropertyReference()->home_object()); |
2426 // stack: value, this; eax: home_object | 2404 // stack: value, this; eax: home_object |
2427 Register scratch = ecx; | 2405 Register scratch = ecx; |
(...skipping 27 matching lines...) Expand all Loading... |
2455 EmitKeyedSuperPropertyStore(prop); | 2433 EmitKeyedSuperPropertyStore(prop); |
2456 break; | 2434 break; |
2457 } | 2435 } |
2458 case KEYED_PROPERTY: { | 2436 case KEYED_PROPERTY: { |
2459 __ push(eax); // Preserve value. | 2437 __ push(eax); // Preserve value. |
2460 VisitForStackValue(prop->obj()); | 2438 VisitForStackValue(prop->obj()); |
2461 VisitForAccumulatorValue(prop->key()); | 2439 VisitForAccumulatorValue(prop->key()); |
2462 __ Move(StoreDescriptor::NameRegister(), eax); | 2440 __ Move(StoreDescriptor::NameRegister(), eax); |
2463 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. | 2441 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. |
2464 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2442 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
2465 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2443 EmitLoadStoreICSlot(slot); |
2466 Handle<Code> ic = | 2444 Handle<Code> ic = |
2467 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2445 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2468 CallIC(ic); | 2446 CallIC(ic); |
2469 break; | 2447 break; |
2470 } | 2448 } |
2471 } | 2449 } |
2472 context()->Plug(eax); | 2450 context()->Plug(eax); |
2473 } | 2451 } |
2474 | 2452 |
2475 | 2453 |
2476 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2454 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
2477 Variable* var, MemOperand location) { | 2455 Variable* var, MemOperand location) { |
2478 __ mov(location, eax); | 2456 __ mov(location, eax); |
2479 if (var->IsContextSlot()) { | 2457 if (var->IsContextSlot()) { |
2480 __ mov(edx, eax); | 2458 __ mov(edx, eax); |
2481 int offset = Context::SlotOffset(var->index()); | 2459 int offset = Context::SlotOffset(var->index()); |
2482 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); | 2460 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); |
2483 } | 2461 } |
2484 } | 2462 } |
2485 | 2463 |
2486 | 2464 |
2487 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2465 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
2488 FeedbackVectorSlot slot) { | 2466 FeedbackVectorSlot slot) { |
2489 if (var->IsUnallocated()) { | 2467 if (var->IsUnallocated()) { |
2490 // Global var, const, or let. | 2468 // Global var, const, or let. |
2491 __ mov(StoreDescriptor::NameRegister(), var->name()); | 2469 __ mov(StoreDescriptor::NameRegister(), var->name()); |
2492 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2470 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
2493 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2471 EmitLoadStoreICSlot(slot); |
2494 CallStoreIC(); | 2472 CallStoreIC(); |
2495 | 2473 |
2496 } else if (var->mode() == LET && op != Token::INIT) { | 2474 } else if (var->mode() == LET && op != Token::INIT) { |
2497 // Non-initializing assignment to let variable needs a write barrier. | 2475 // Non-initializing assignment to let variable needs a write barrier. |
2498 DCHECK(!var->IsLookupSlot()); | 2476 DCHECK(!var->IsLookupSlot()); |
2499 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2477 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2500 Label assign; | 2478 Label assign; |
2501 MemOperand location = VarOperand(var, ecx); | 2479 MemOperand location = VarOperand(var, ecx); |
2502 __ mov(edx, location); | 2480 __ mov(edx, location); |
2503 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2481 __ cmp(edx, isolate()->factory()->the_hole_value()); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2589 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2567 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2590 // Assignment to a property, using a named store IC. | 2568 // Assignment to a property, using a named store IC. |
2591 // eax : value | 2569 // eax : value |
2592 // esp[0] : receiver | 2570 // esp[0] : receiver |
2593 Property* prop = expr->target()->AsProperty(); | 2571 Property* prop = expr->target()->AsProperty(); |
2594 DCHECK(prop != NULL); | 2572 DCHECK(prop != NULL); |
2595 DCHECK(prop->key()->IsLiteral()); | 2573 DCHECK(prop->key()->IsLiteral()); |
2596 | 2574 |
2597 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2575 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
2598 __ pop(StoreDescriptor::ReceiverRegister()); | 2576 __ pop(StoreDescriptor::ReceiverRegister()); |
2599 if (FLAG_vector_stores) { | 2577 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2600 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2578 CallStoreIC(); |
2601 CallStoreIC(); | |
2602 } else { | |
2603 CallStoreIC(expr->AssignmentFeedbackId()); | |
2604 } | |
2605 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2579 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2606 context()->Plug(eax); | 2580 context()->Plug(eax); |
2607 } | 2581 } |
2608 | 2582 |
2609 | 2583 |
2610 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2584 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2611 // Assignment to named property of super. | 2585 // Assignment to named property of super. |
2612 // eax : value | 2586 // eax : value |
2613 // stack : receiver ('this'), home_object | 2587 // stack : receiver ('this'), home_object |
2614 DCHECK(prop != NULL); | 2588 DCHECK(prop != NULL); |
(...skipping 25 matching lines...) Expand all Loading... |
2640 // Assignment to a property, using a keyed store IC. | 2614 // Assignment to a property, using a keyed store IC. |
2641 // eax : value | 2615 // eax : value |
2642 // esp[0] : key | 2616 // esp[0] : key |
2643 // esp[kPointerSize] : receiver | 2617 // esp[kPointerSize] : receiver |
2644 | 2618 |
2645 __ pop(StoreDescriptor::NameRegister()); // Key. | 2619 __ pop(StoreDescriptor::NameRegister()); // Key. |
2646 __ pop(StoreDescriptor::ReceiverRegister()); | 2620 __ pop(StoreDescriptor::ReceiverRegister()); |
2647 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2621 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2648 Handle<Code> ic = | 2622 Handle<Code> ic = |
2649 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2623 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2650 if (FLAG_vector_stores) { | 2624 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2651 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2625 CallIC(ic); |
2652 CallIC(ic); | |
2653 } else { | |
2654 CallIC(ic, expr->AssignmentFeedbackId()); | |
2655 } | |
2656 | |
2657 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2626 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2658 context()->Plug(eax); | 2627 context()->Plug(eax); |
2659 } | 2628 } |
2660 | 2629 |
2661 | 2630 |
2662 void FullCodeGenerator::VisitProperty(Property* expr) { | 2631 void FullCodeGenerator::VisitProperty(Property* expr) { |
2663 Comment cmnt(masm_, "[ Property"); | 2632 Comment cmnt(masm_, "[ Property"); |
2664 SetExpressionPosition(expr); | 2633 SetExpressionPosition(expr); |
2665 | 2634 |
2666 Expression* key = expr->key(); | 2635 Expression* key = expr->key(); |
(...skipping 1854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4521 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4490 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
4522 Token::ASSIGN, expr->CountSlot()); | 4491 Token::ASSIGN, expr->CountSlot()); |
4523 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4492 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4524 context()->Plug(eax); | 4493 context()->Plug(eax); |
4525 } | 4494 } |
4526 break; | 4495 break; |
4527 case NAMED_PROPERTY: { | 4496 case NAMED_PROPERTY: { |
4528 __ mov(StoreDescriptor::NameRegister(), | 4497 __ mov(StoreDescriptor::NameRegister(), |
4529 prop->key()->AsLiteral()->value()); | 4498 prop->key()->AsLiteral()->value()); |
4530 __ pop(StoreDescriptor::ReceiverRegister()); | 4499 __ pop(StoreDescriptor::ReceiverRegister()); |
4531 if (FLAG_vector_stores) { | 4500 EmitLoadStoreICSlot(expr->CountSlot()); |
4532 EmitLoadStoreICSlot(expr->CountSlot()); | 4501 CallStoreIC(); |
4533 CallStoreIC(); | |
4534 } else { | |
4535 CallStoreIC(expr->CountStoreFeedbackId()); | |
4536 } | |
4537 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4502 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4538 if (expr->is_postfix()) { | 4503 if (expr->is_postfix()) { |
4539 if (!context()->IsEffect()) { | 4504 if (!context()->IsEffect()) { |
4540 context()->PlugTOS(); | 4505 context()->PlugTOS(); |
4541 } | 4506 } |
4542 } else { | 4507 } else { |
4543 context()->Plug(eax); | 4508 context()->Plug(eax); |
4544 } | 4509 } |
4545 break; | 4510 break; |
4546 } | 4511 } |
(...skipping 17 matching lines...) Expand all Loading... |
4564 } else { | 4529 } else { |
4565 context()->Plug(eax); | 4530 context()->Plug(eax); |
4566 } | 4531 } |
4567 break; | 4532 break; |
4568 } | 4533 } |
4569 case KEYED_PROPERTY: { | 4534 case KEYED_PROPERTY: { |
4570 __ pop(StoreDescriptor::NameRegister()); | 4535 __ pop(StoreDescriptor::NameRegister()); |
4571 __ pop(StoreDescriptor::ReceiverRegister()); | 4536 __ pop(StoreDescriptor::ReceiverRegister()); |
4572 Handle<Code> ic = | 4537 Handle<Code> ic = |
4573 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 4538 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
4574 if (FLAG_vector_stores) { | 4539 EmitLoadStoreICSlot(expr->CountSlot()); |
4575 EmitLoadStoreICSlot(expr->CountSlot()); | 4540 CallIC(ic); |
4576 CallIC(ic); | |
4577 } else { | |
4578 CallIC(ic, expr->CountStoreFeedbackId()); | |
4579 } | |
4580 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4541 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4581 if (expr->is_postfix()) { | 4542 if (expr->is_postfix()) { |
4582 // Result is on the stack | 4543 // Result is on the stack |
4583 if (!context()->IsEffect()) { | 4544 if (!context()->IsEffect()) { |
4584 context()->PlugTOS(); | 4545 context()->PlugTOS(); |
4585 } | 4546 } |
4586 } else { | 4547 } else { |
4587 context()->Plug(eax); | 4548 context()->Plug(eax); |
4588 } | 4549 } |
4589 break; | 4550 break; |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4869 void FullCodeGenerator::ClearPendingMessage() { | 4830 void FullCodeGenerator::ClearPendingMessage() { |
4870 DCHECK(!result_register().is(edx)); | 4831 DCHECK(!result_register().is(edx)); |
4871 ExternalReference pending_message_obj = | 4832 ExternalReference pending_message_obj = |
4872 ExternalReference::address_of_pending_message_obj(isolate()); | 4833 ExternalReference::address_of_pending_message_obj(isolate()); |
4873 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 4834 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
4874 __ mov(Operand::StaticVariable(pending_message_obj), edx); | 4835 __ mov(Operand::StaticVariable(pending_message_obj), edx); |
4875 } | 4836 } |
4876 | 4837 |
4877 | 4838 |
4878 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { | 4839 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { |
4879 DCHECK(FLAG_vector_stores && !slot.IsInvalid()); | 4840 DCHECK(!slot.IsInvalid()); |
4880 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), | 4841 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), |
4881 Immediate(SmiFromSlot(slot))); | 4842 Immediate(SmiFromSlot(slot))); |
4882 } | 4843 } |
4883 | 4844 |
4884 | 4845 |
4885 #undef __ | 4846 #undef __ |
4886 | 4847 |
4887 | 4848 |
4888 static const byte kJnsInstruction = 0x79; | 4849 static const byte kJnsInstruction = 0x79; |
4889 static const byte kJnsOffset = 0x11; | 4850 static const byte kJnsOffset = 0x11; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4959 Assembler::target_address_at(call_target_address, | 4920 Assembler::target_address_at(call_target_address, |
4960 unoptimized_code)); | 4921 unoptimized_code)); |
4961 return OSR_AFTER_STACK_CHECK; | 4922 return OSR_AFTER_STACK_CHECK; |
4962 } | 4923 } |
4963 | 4924 |
4964 | 4925 |
4965 } // namespace internal | 4926 } // namespace internal |
4966 } // namespace v8 | 4927 } // namespace v8 |
4967 | 4928 |
4968 #endif // V8_TARGET_ARCH_IA32 | 4929 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |