OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
719 if (new_space_.Contains(obj)) { | 719 if (new_space_.Contains(obj)) { |
720 new_space_.RecordAllocation(obj); | 720 new_space_.RecordAllocation(obj); |
721 } else { | 721 } else { |
722 new_space_.RecordPromotion(obj); | 722 new_space_.RecordPromotion(obj); |
723 } | 723 } |
724 } | 724 } |
725 } | 725 } |
726 #endif // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | 726 #endif // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) |
727 | 727 |
728 | 728 |
729 | |
729 HeapObject* Heap::MigrateObject(HeapObject* source, | 730 HeapObject* Heap::MigrateObject(HeapObject* source, |
730 HeapObject* target, | 731 HeapObject* target, |
731 int size) { | 732 int size) { |
732 void** src = reinterpret_cast<void**>(source->address()); | 733 // Copy the content of source to target. |
733 void** dst = reinterpret_cast<void**>(target->address()); | 734 CopyBlock(reinterpret_cast<Object**>(target->address()), |
734 | 735 reinterpret_cast<Object**>(source->address()), |
735 // Use block copying memcpy if the object we're migrating is big | 736 size); |
736 // enough to justify the extra call/setup overhead. | |
737 static const int kBlockCopyLimit = 16 * kPointerSize; | |
738 | |
739 if (size >= kBlockCopyLimit) { | |
740 memcpy(dst, src, size); | |
741 } else { | |
742 int remaining = size / kPointerSize; | |
743 do { | |
744 remaining--; | |
745 *dst++ = *src++; | |
746 } while (remaining > 0); | |
747 } | |
748 | 737 |
749 // Set the forwarding address. | 738 // Set the forwarding address. |
750 source->set_map_word(MapWord::FromForwardingAddress(target)); | 739 source->set_map_word(MapWord::FromForwardingAddress(target)); |
751 | 740 |
752 // Update NewSpace stats if necessary. | 741 // Update NewSpace stats if necessary. |
753 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | 742 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) |
754 RecordCopiedObject(target); | 743 RecordCopiedObject(target); |
755 #endif | 744 #endif |
756 | 745 |
757 return target; | 746 return target; |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1582 result = lo_space_->AllocateRawCode(obj_size); | 1571 result = lo_space_->AllocateRawCode(obj_size); |
1583 } else { | 1572 } else { |
1584 result = code_space_->AllocateRaw(obj_size); | 1573 result = code_space_->AllocateRaw(obj_size); |
1585 } | 1574 } |
1586 | 1575 |
1587 if (result->IsFailure()) return result; | 1576 if (result->IsFailure()) return result; |
1588 | 1577 |
1589 // Copy code object. | 1578 // Copy code object. |
1590 Address old_addr = code->address(); | 1579 Address old_addr = code->address(); |
1591 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); | 1580 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); |
1592 memcpy(new_addr, old_addr, obj_size); | 1581 CopyBlock(reinterpret_cast<Object**>(new_addr), |
1593 | 1582 reinterpret_cast<Object**>(old_addr), |
1583 obj_size); | |
1594 // Relocate the copy. | 1584 // Relocate the copy. |
1595 Code* new_code = Code::cast(result); | 1585 Code* new_code = Code::cast(result); |
1596 new_code->Relocate(new_addr - old_addr); | 1586 new_code->Relocate(new_addr - old_addr); |
1597 return new_code; | 1587 return new_code; |
1598 } | 1588 } |
1599 | 1589 |
1600 | 1590 |
1601 Object* Heap::Allocate(Map* map, AllocationSpace space) { | 1591 Object* Heap::Allocate(Map* map, AllocationSpace space) { |
1602 ASSERT(gc_state_ == NOT_IN_GC); | 1592 ASSERT(gc_state_ == NOT_IN_GC); |
1603 ASSERT(map->instance_type() != MAP_TYPE); | 1593 ASSERT(map->instance_type() != MAP_TYPE); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1650 Object* Heap::AllocateArgumentsObject(Object* callee, int length) { | 1640 Object* Heap::AllocateArgumentsObject(Object* callee, int length) { |
1651 // To get fast allocation and map sharing for arguments objects we | 1641 // To get fast allocation and map sharing for arguments objects we |
1652 // allocate them based on an arguments boilerplate. | 1642 // allocate them based on an arguments boilerplate. |
1653 | 1643 |
1654 // This calls Copy directly rather than using Heap::AllocateRaw so we | 1644 // This calls Copy directly rather than using Heap::AllocateRaw so we |
1655 // duplicate the check here. | 1645 // duplicate the check here. |
1656 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); | 1646 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); |
1657 | 1647 |
1658 JSObject* boilerplate = | 1648 JSObject* boilerplate = |
1659 Top::context()->global_context()->arguments_boilerplate(); | 1649 Top::context()->global_context()->arguments_boilerplate(); |
1660 Object* result = boilerplate->Copy(); | 1650 Object* result = CopyJSObject(boilerplate); |
1661 if (result->IsFailure()) return result; | 1651 if (result->IsFailure()) return result; |
1662 | 1652 |
1663 Object* obj = JSObject::cast(result)->properties(); | 1653 Object* obj = JSObject::cast(result)->properties(); |
1664 FixedArray::cast(obj)->set(arguments_callee_index, callee); | 1654 FixedArray::cast(obj)->set(arguments_callee_index, callee); |
1665 FixedArray::cast(obj)->set(arguments_length_index, Smi::FromInt(length)); | 1655 FixedArray::cast(obj)->set(arguments_length_index, Smi::FromInt(length)); |
1666 | 1656 |
1667 // Allocate the fixed array. | 1657 // Allocate the fixed array. |
1668 obj = Heap::AllocateFixedArray(length); | 1658 obj = Heap::AllocateFixedArray(length); |
1669 if (obj->IsFailure()) return obj; | 1659 if (obj->IsFailure()) return obj; |
1670 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); | 1660 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1757 Object* initial_map = AllocateInitialMap(constructor); | 1747 Object* initial_map = AllocateInitialMap(constructor); |
1758 if (initial_map->IsFailure()) return initial_map; | 1748 if (initial_map->IsFailure()) return initial_map; |
1759 constructor->set_initial_map(Map::cast(initial_map)); | 1749 constructor->set_initial_map(Map::cast(initial_map)); |
1760 Map::cast(initial_map)->set_constructor(constructor); | 1750 Map::cast(initial_map)->set_constructor(constructor); |
1761 } | 1751 } |
1762 // Allocate the object based on the constructors initial map. | 1752 // Allocate the object based on the constructors initial map. |
1763 return AllocateJSObjectFromMap(constructor->initial_map(), pretenure); | 1753 return AllocateJSObjectFromMap(constructor->initial_map(), pretenure); |
1764 } | 1754 } |
1765 | 1755 |
1766 | 1756 |
1757 Object* Heap::CopyJSObject(JSObject* source) { | |
1758 // Never used to copy functions. If functions need to be copied we | |
1759 // have to be careful to clear the literals array. | |
1760 ASSERT(!source->IsJSFunction()); | |
1761 | |
1762 // Make the clone. | |
1763 Map* map = source->map(); | |
1764 int object_size = map->instance_size(); | |
1765 Object* clone = new_space_.AllocateRaw(object_size); | |
Kasper Lund
2008/10/22 08:17:21
Extra space before new_space_.
| |
1766 if (clone->IsFailure()) return clone; | |
1767 ASSERT(Heap::InNewSpace(clone)); | |
1768 | |
1769 // Copy the content. | |
1770 CopyBlock(reinterpret_cast<Object**>(HeapObject::cast(clone)->address()), | |
1771 reinterpret_cast<Object**>(source->address()), | |
1772 object_size); | |
1773 | |
1774 FixedArray* elements = FixedArray::cast(source->elements()); | |
1775 FixedArray* properties = FixedArray::cast(source->properties()); | |
1776 // Update elements if necessary. | |
1777 if (elements->length()> 0) { | |
1778 Object* elem = Heap::CopyFixedArray(elements); | |
Kasper Lund
2008/10/22 08:17:21
Extra space before Heap.
| |
1779 if (elem->IsFailure()) return elem; | |
1780 JSObject::cast(clone)->set_elements(FixedArray::cast(elem)); | |
1781 } | |
1782 // Update properties if necessary. | |
1783 if (properties->length() > 0) { | |
1784 Object* prop = Heap::CopyFixedArray(properties); | |
1785 if (prop->IsFailure()) return prop; | |
1786 JSObject::cast(clone)->set_properties(FixedArray::cast(prop)); | |
1787 } | |
1788 // Return the new clone. | |
1789 return clone; | |
1790 } | |
1791 | |
1792 | |
1767 Object* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor, | 1793 Object* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor, |
1768 JSGlobalProxy* object) { | 1794 JSGlobalProxy* object) { |
1769 // Allocate initial map if absent. | 1795 // Allocate initial map if absent. |
1770 if (!constructor->has_initial_map()) { | 1796 if (!constructor->has_initial_map()) { |
1771 Object* initial_map = AllocateInitialMap(constructor); | 1797 Object* initial_map = AllocateInitialMap(constructor); |
1772 if (initial_map->IsFailure()) return initial_map; | 1798 if (initial_map->IsFailure()) return initial_map; |
1773 constructor->set_initial_map(Map::cast(initial_map)); | 1799 constructor->set_initial_map(Map::cast(initial_map)); |
1774 Map::cast(initial_map)->set_constructor(constructor); | 1800 Map::cast(initial_map)->set_constructor(constructor); |
1775 } | 1801 } |
1776 | 1802 |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2057 // Allocate the raw data for a fixed array. | 2083 // Allocate the raw data for a fixed array. |
2058 int size = FixedArray::SizeFor(length); | 2084 int size = FixedArray::SizeFor(length); |
2059 return (size > MaxHeapObjectSize()) | 2085 return (size > MaxHeapObjectSize()) |
2060 ? lo_space_->AllocateRawFixedArray(size) | 2086 ? lo_space_->AllocateRawFixedArray(size) |
2061 : new_space_.AllocateRaw(size); | 2087 : new_space_.AllocateRaw(size); |
2062 } | 2088 } |
2063 | 2089 |
2064 | 2090 |
2065 Object* Heap::CopyFixedArray(FixedArray* src) { | 2091 Object* Heap::CopyFixedArray(FixedArray* src) { |
2066 int len = src->length(); | 2092 int len = src->length(); |
2067 Object* obj = Heap::AllocateRawFixedArray(len); | 2093 Object* obj = AllocateRawFixedArray(len); |
2068 if (obj->IsFailure()) return obj; | 2094 if (obj->IsFailure()) return obj; |
2095 if (Heap::InNewSpace(obj)) { | |
2096 HeapObject* dst = HeapObject::cast(obj); | |
2097 CopyBlock(reinterpret_cast<Object**>(dst->address()), | |
2098 reinterpret_cast<Object**>(src->address()), | |
2099 FixedArray::SizeFor(len)); | |
2100 return obj; | |
2101 } | |
2069 HeapObject::cast(obj)->set_map(src->map()); | 2102 HeapObject::cast(obj)->set_map(src->map()); |
2070 FixedArray* result = FixedArray::cast(obj); | 2103 FixedArray* result = FixedArray::cast(obj); |
2071 result->set_length(len); | 2104 result->set_length(len); |
2072 FixedArray::WriteBarrierMode mode = result->GetWriteBarrierMode(); | |
2073 // Copy the content | 2105 // Copy the content |
2074 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); | 2106 for (int i = 0; i < len; i++) result->set(i, src->get(i)); |
2075 return result; | 2107 return result; |
2076 } | 2108 } |
2077 | 2109 |
2078 | 2110 |
2079 Object* Heap::AllocateFixedArray(int length) { | 2111 Object* Heap::AllocateFixedArray(int length) { |
2080 Object* result = AllocateRawFixedArray(length); | 2112 Object* result = AllocateRawFixedArray(length); |
2081 if (!result->IsFailure()) { | 2113 if (!result->IsFailure()) { |
2082 // Initialize header. | 2114 // Initialize header. |
2083 reinterpret_cast<Array*>(result)->set_map(fixed_array_map()); | 2115 reinterpret_cast<Array*>(result)->set_map(fixed_array_map()); |
2084 FixedArray* array = FixedArray::cast(result); | 2116 FixedArray* array = FixedArray::cast(result); |
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3128 #ifdef DEBUG | 3160 #ifdef DEBUG |
3129 bool Heap::GarbageCollectionGreedyCheck() { | 3161 bool Heap::GarbageCollectionGreedyCheck() { |
3130 ASSERT(FLAG_gc_greedy); | 3162 ASSERT(FLAG_gc_greedy); |
3131 if (Bootstrapper::IsActive()) return true; | 3163 if (Bootstrapper::IsActive()) return true; |
3132 if (disallow_allocation_failure()) return true; | 3164 if (disallow_allocation_failure()) return true; |
3133 return CollectGarbage(0, NEW_SPACE); | 3165 return CollectGarbage(0, NEW_SPACE); |
3134 } | 3166 } |
3135 #endif | 3167 #endif |
3136 | 3168 |
3137 } } // namespace v8::internal | 3169 } } // namespace v8::internal |
OLD | NEW |