Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 7945009: Merge experimental/gc branch to the bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 index -= object->map()->inobject_properties(); 783 index -= object->map()->inobject_properties();
784 784
785 if (index < 0) { 785 if (index < 0) {
786 // Set the property straight into the object. 786 // Set the property straight into the object.
787 int offset = object->map()->instance_size() + (index * kPointerSize); 787 int offset = object->map()->instance_size() + (index * kPointerSize);
788 __ mov(FieldOperand(receiver_reg, offset), eax); 788 __ mov(FieldOperand(receiver_reg, offset), eax);
789 789
790 // Update the write barrier for the array address. 790 // Update the write barrier for the array address.
791 // Pass the value being stored in the now unused name_reg. 791 // Pass the value being stored in the now unused name_reg.
792 __ mov(name_reg, Operand(eax)); 792 __ mov(name_reg, Operand(eax));
793 __ RecordWrite(receiver_reg, offset, name_reg, scratch); 793 __ RecordWriteField(receiver_reg,
794 offset,
795 name_reg,
796 scratch,
797 kDontSaveFPRegs);
794 } else { 798 } else {
795 // Write to the properties array. 799 // Write to the properties array.
796 int offset = index * kPointerSize + FixedArray::kHeaderSize; 800 int offset = index * kPointerSize + FixedArray::kHeaderSize;
797 // Get the properties array (optimistically). 801 // Get the properties array (optimistically).
798 __ mov(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 802 __ mov(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
799 __ mov(FieldOperand(scratch, offset), eax); 803 __ mov(FieldOperand(scratch, offset), eax);
800 804
801 // Update the write barrier for the array address. 805 // Update the write barrier for the array address.
802 // Pass the value being stored in the now unused name_reg. 806 // Pass the value being stored in the now unused name_reg.
803 __ mov(name_reg, Operand(eax)); 807 __ mov(name_reg, Operand(eax));
804 __ RecordWrite(scratch, offset, name_reg, receiver_reg); 808 __ RecordWriteField(scratch,
809 offset,
810 name_reg,
811 receiver_reg,
812 kDontSaveFPRegs);
805 } 813 }
806 814
807 // Return the value (register eax). 815 // Return the value (register eax).
808 __ ret(0); 816 __ ret(0);
809 } 817 }
810 818
811 819
812 // Generate code to check that a global property cell is empty. Create 820 // Generate code to check that a global property cell is empty. Create
813 // the property cell at compilation time if no cell exists for the 821 // the property cell at compilation time if no cell exists for the
814 // property. 822 // property.
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 1447
1440 // Get the elements array of the object. 1448 // Get the elements array of the object.
1441 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1449 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1442 1450
1443 // Check that the elements are in fast mode and writable. 1451 // Check that the elements are in fast mode and writable.
1444 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1452 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1445 Immediate(factory()->fixed_array_map())); 1453 Immediate(factory()->fixed_array_map()));
1446 __ j(not_equal, &call_builtin); 1454 __ j(not_equal, &call_builtin);
1447 1455
1448 if (argc == 1) { // Otherwise fall through to call builtin. 1456 if (argc == 1) { // Otherwise fall through to call builtin.
1449 Label exit, with_write_barrier, attempt_to_grow_elements; 1457 Label exit, attempt_to_grow_elements, with_write_barrier;
1450 1458
1451 // Get the array's length into eax and calculate new length. 1459 // Get the array's length into eax and calculate new length.
1452 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1460 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1453 STATIC_ASSERT(kSmiTagSize == 1); 1461 STATIC_ASSERT(kSmiTagSize == 1);
1454 STATIC_ASSERT(kSmiTag == 0); 1462 STATIC_ASSERT(kSmiTag == 0);
1455 __ add(Operand(eax), Immediate(Smi::FromInt(argc))); 1463 __ add(Operand(eax), Immediate(Smi::FromInt(argc)));
1456 1464
1457 // Get the element's length into ecx. 1465 // Get the element's length into ecx.
1458 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); 1466 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
1459 1467
(...skipping 12 matching lines...) Expand all
1472 __ mov(Operand(edx, 0), ecx); 1480 __ mov(Operand(edx, 0), ecx);
1473 1481
1474 // Check if value is a smi. 1482 // Check if value is a smi.
1475 __ JumpIfNotSmi(ecx, &with_write_barrier); 1483 __ JumpIfNotSmi(ecx, &with_write_barrier);
1476 1484
1477 __ bind(&exit); 1485 __ bind(&exit);
1478 __ ret((argc + 1) * kPointerSize); 1486 __ ret((argc + 1) * kPointerSize);
1479 1487
1480 __ bind(&with_write_barrier); 1488 __ bind(&with_write_barrier);
1481 1489
1482 __ InNewSpace(ebx, ecx, equal, &exit); 1490 __ RecordWrite(
1491 ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
1483 1492
1484 __ RecordWriteHelper(ebx, edx, ecx);
1485 __ ret((argc + 1) * kPointerSize); 1493 __ ret((argc + 1) * kPointerSize);
1486 1494
1487 __ bind(&attempt_to_grow_elements); 1495 __ bind(&attempt_to_grow_elements);
1488 if (!FLAG_inline_new) { 1496 if (!FLAG_inline_new) {
1489 __ jmp(&call_builtin); 1497 __ jmp(&call_builtin);
1490 } 1498 }
1491 1499
1500 // We could be lucky and the elements array could be at the top of
1501 // new-space. In this case we can just grow it in place by moving the
1502 // allocation pointer up.
1503
1492 ExternalReference new_space_allocation_top = 1504 ExternalReference new_space_allocation_top =
1493 ExternalReference::new_space_allocation_top_address(isolate()); 1505 ExternalReference::new_space_allocation_top_address(isolate());
1494 ExternalReference new_space_allocation_limit = 1506 ExternalReference new_space_allocation_limit =
1495 ExternalReference::new_space_allocation_limit_address(isolate()); 1507 ExternalReference::new_space_allocation_limit_address(isolate());
1496 1508
1497 const int kAllocationDelta = 4; 1509 const int kAllocationDelta = 4;
1498 // Load top. 1510 // Load top.
1499 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); 1511 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
1500 1512
1501 // Check if it's the end of elements. 1513 // Check if it's the end of elements.
(...skipping 11 matching lines...) Expand all
1513 __ mov(ecx, Operand(esp, argc * kPointerSize)); 1525 __ mov(ecx, Operand(esp, argc * kPointerSize));
1514 1526
1515 // Push the argument... 1527 // Push the argument...
1516 __ mov(Operand(edx, 0), ecx); 1528 __ mov(Operand(edx, 0), ecx);
1517 // ... and fill the rest with holes. 1529 // ... and fill the rest with holes.
1518 for (int i = 1; i < kAllocationDelta; i++) { 1530 for (int i = 1; i < kAllocationDelta; i++) {
1519 __ mov(Operand(edx, i * kPointerSize), 1531 __ mov(Operand(edx, i * kPointerSize),
1520 Immediate(factory()->the_hole_value())); 1532 Immediate(factory()->the_hole_value()));
1521 } 1533 }
1522 1534
1535 // We know the elements array is in new space so we don't need the
1536 // remembered set, but we just pushed a value onto it so we may have to
1537 // tell the incremental marker to rescan the object that we just grew. We
1538 // don't need to worry about the holes because they are in old space and
1539 // already marked black.
1540 __ RecordWrite(ebx, edx, ecx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
1541
1523 // Restore receiver to edx as finish sequence assumes it's here. 1542 // Restore receiver to edx as finish sequence assumes it's here.
1524 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1543 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1525 1544
1526 // Increment element's and array's sizes. 1545 // Increment element's and array's sizes.
1527 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), 1546 __ add(FieldOperand(ebx, FixedArray::kLengthOffset),
1528 Immediate(Smi::FromInt(kAllocationDelta))); 1547 Immediate(Smi::FromInt(kAllocationDelta)));
1548
1549 // NOTE: This only happen in new-space, where we don't
1550 // care about the black-byte-count on pages. Otherwise we should
1551 // update that too if the object is black.
1552
1529 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1553 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1530 1554
1531 // Elements are in new space, so write barrier is not required.
1532 __ ret((argc + 1) * kPointerSize); 1555 __ ret((argc + 1) * kPointerSize);
1533 } 1556 }
1534 1557
1535 __ bind(&call_builtin); 1558 __ bind(&call_builtin);
1536 __ TailCallExternalReference( 1559 __ TailCallExternalReference(
1537 ExternalReference(Builtins::c_ArrayPush, isolate()), 1560 ExternalReference(Builtins::c_ArrayPush, isolate()),
1538 argc + 1, 1561 argc + 1,
1539 1); 1562 1);
1540 } 1563 }
1541 1564
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 // -- edx : receiver 2620 // -- edx : receiver
2598 // -- esp[0] : return address 2621 // -- esp[0] : return address
2599 // ----------------------------------- 2622 // -----------------------------------
2600 Label miss; 2623 Label miss;
2601 2624
2602 // Check that the map of the global has not changed. 2625 // Check that the map of the global has not changed.
2603 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2626 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2604 Immediate(Handle<Map>(object->map()))); 2627 Immediate(Handle<Map>(object->map())));
2605 __ j(not_equal, &miss); 2628 __ j(not_equal, &miss);
2606 2629
2607
2608 // Compute the cell operand to use. 2630 // Compute the cell operand to use.
2609 Operand cell_operand = Operand::Cell(Handle<JSGlobalPropertyCell>(cell)); 2631 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2610 if (Serializer::enabled()) { 2632 Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset);
2611 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2612 cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset);
2613 }
2614 2633
2615 // Check that the value in the cell is not the hole. If it is, this 2634 // Check that the value in the cell is not the hole. If it is, this
2616 // cell could have been deleted and reintroducing the global needs 2635 // cell could have been deleted and reintroducing the global needs
2617 // to update the property details in the property dictionary of the 2636 // to update the property details in the property dictionary of the
2618 // global object. We bail out to the runtime system to do that. 2637 // global object. We bail out to the runtime system to do that.
2619 __ cmp(cell_operand, factory()->the_hole_value()); 2638 __ cmp(cell_operand, factory()->the_hole_value());
2620 __ j(equal, &miss); 2639 __ j(equal, &miss);
2621 2640
2622 // Store the value in the cell. 2641 // Store the value in the cell.
2623 __ mov(cell_operand, eax); 2642 __ mov(cell_operand, eax);
2643 Label done;
2644 __ test(eax, Immediate(kSmiTagMask));
2645 __ j(zero, &done);
2646
2647 __ mov(ecx, eax);
2648 __ lea(edx, cell_operand);
2649 // Cells are always in the remembered set.
2650 __ RecordWrite(ebx, // Object.
2651 edx, // Address.
2652 ecx, // Value.
2653 kDontSaveFPRegs,
2654 OMIT_REMEMBERED_SET,
2655 OMIT_SMI_CHECK);
2624 2656
2625 // Return the value (register eax). 2657 // Return the value (register eax).
2658 __ bind(&done);
2659
2626 Counters* counters = isolate()->counters(); 2660 Counters* counters = isolate()->counters();
2627 __ IncrementCounter(counters->named_store_global_inline(), 1); 2661 __ IncrementCounter(counters->named_store_global_inline(), 1);
2628 __ ret(0); 2662 __ ret(0);
2629 2663
2630 // Handle store cache miss. 2664 // Handle store cache miss.
2631 __ bind(&miss); 2665 __ bind(&miss);
2632 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); 2666 __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
2633 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2667 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2634 __ jmp(ic, RelocInfo::CODE_TARGET); 2668 __ jmp(ic, RelocInfo::CODE_TARGET);
2635 2669
(...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3868 if (is_js_array) { 3902 if (is_js_array) {
3869 // Check that the key is within bounds. 3903 // Check that the key is within bounds.
3870 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. 3904 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
3871 __ j(above_equal, &miss_force_generic); 3905 __ j(above_equal, &miss_force_generic);
3872 } else { 3906 } else {
3873 // Check that the key is within bounds. 3907 // Check that the key is within bounds.
3874 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. 3908 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis.
3875 __ j(above_equal, &miss_force_generic); 3909 __ j(above_equal, &miss_force_generic);
3876 } 3910 }
3877 3911
3878 // Do the store and update the write barrier. Make sure to preserve 3912 // Do the store and update the write barrier.
3879 // the value in register eax. 3913 __ lea(ecx, FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize));
3914 __ mov(Operand(ecx, 0), eax);
3915 // Make sure to preserve the value in register eax.
3880 __ mov(edx, Operand(eax)); 3916 __ mov(edx, Operand(eax));
3881 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); 3917 __ RecordWrite(edi, ecx, edx, kDontSaveFPRegs);
3882 __ RecordWrite(edi, 0, edx, ecx);
3883 3918
3884 // Done. 3919 // Done.
3885 __ ret(0); 3920 __ ret(0);
3886 3921
3887 // Handle store cache miss, replacing the ic with the generic stub. 3922 // Handle store cache miss, replacing the ic with the generic stub.
3888 __ bind(&miss_force_generic); 3923 __ bind(&miss_force_generic);
3889 Handle<Code> ic_force_generic = 3924 Handle<Code> ic_force_generic =
3890 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3925 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3891 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3926 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3892 } 3927 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3984 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 4019 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3985 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 4020 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3986 } 4021 }
3987 4022
3988 4023
3989 #undef __ 4024 #undef __
3990 4025
3991 } } // namespace v8::internal 4026 } } // namespace v8::internal
3992 4027
3993 #endif // V8_TARGET_ARCH_IA32 4028 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698