Author: [email protected]
Date: Thu Jun 18 07:06:36 2009
New Revision: 2219
Modified:
branches/bleeding_edge/src/heap-inl.h
branches/bleeding_edge/src/heap.cc
branches/bleeding_edge/src/heap.h
branches/bleeding_edge/src/ia32/builtins-ia32.cc
branches/bleeding_edge/src/mark-compact.cc
branches/bleeding_edge/src/serialize.cc
branches/bleeding_edge/src/spaces.h
branches/bleeding_edge/test/cctest/test-heap.cc
branches/bleeding_edge/test/cctest/test-mark-compact.cc
Log:
Changed allocation to allow large objects to be allocated in new space.
This avoids back-to-back mark-sweep collections.
Review URL: http://codereview.chromium.org/136001
Modified: branches/bleeding_edge/src/heap-inl.h
==============================================================================
--- branches/bleeding_edge/src/heap-inl.h (original)
+++ branches/bleeding_edge/src/heap-inl.h Thu Jun 18 07:06:36 2009
@@ -34,7 +34,7 @@
namespace v8 {
namespace internal {
-int Heap::MaxHeapObjectSize() {
+int Heap::MaxObjectSizeInPagedSpace() {
return Page::kMaxHeapObjectSize;
}
Modified: branches/bleeding_edge/src/heap.cc
==============================================================================
--- branches/bleeding_edge/src/heap.cc (original)
+++ branches/bleeding_edge/src/heap.cc Thu Jun 18 07:06:36 2009
@@ -943,17 +943,15 @@
// If the object should be promoted, we try to copy it to old space.
if (ShouldBePromoted(object->address(), object_size)) {
- OldSpace* target_space = Heap::TargetSpace(object);
- ASSERT(target_space == Heap::old_pointer_space_ ||
- target_space == Heap::old_data_space_);
- Object* result = target_space->AllocateRaw(object_size);
- if (!result->IsFailure()) {
- HeapObject* target = HeapObject::cast(result);
- if (target_space == Heap::old_pointer_space_) {
+ Object* result;
+ if (object_size > MaxObjectSizeInPagedSpace()) {
+ result = lo_space_->AllocateRawFixedArray(object_size);
+ if (!result->IsFailure()) {
// Save the from-space object pointer and its map pointer at the
// top of the to space to be swept and copied later. Write the
// forwarding address over the map word of the from-space
// object.
+ HeapObject* target = HeapObject::cast(result);
promotion_queue.insert(object, first_word.ToMap());
object->set_map_word(MapWord::FromForwardingAddress(target));
@@ -964,21 +962,45 @@
node->set_size(object_size);
*p = target;
- } else {
- // Objects promoted to the data space can be copied immediately
- // and not revisited---we will never sweep that space for
- // pointers and the copied objects do not contain pointers to
- // new space objects.
- *p = MigrateObject(object, target, object_size);
+ return;
+ }
+ } else {
+ OldSpace* target_space = Heap::TargetSpace(object);
+ ASSERT(target_space == Heap::old_pointer_space_ ||
+ target_space == Heap::old_data_space_);
+ result = target_space->AllocateRaw(object_size);
+ if (!result->IsFailure()) {
+ HeapObject* target = HeapObject::cast(result);
+ if (target_space == Heap::old_pointer_space_) {
+ // Save the from-space object pointer and its map pointer at the
+ // top of the to space to be swept and copied later. Write the
+ // forwarding address over the map word of the from-space
+ // object.
+ promotion_queue.insert(object, first_word.ToMap());
+ object->set_map_word(MapWord::FromForwardingAddress(target));
+
+ // Give the space allocated for the result a proper map by
+ // treating it as a free list node (not linked into the free
+ // list).
+ FreeListNode* node =
FreeListNode::FromAddress(target->address());
+ node->set_size(object_size);
+
+ *p = target;
+ } else {
+ // Objects promoted to the data space can be copied immediately
+ // and not revisited---we will never sweep that space for
+ // pointers and the copied objects do not contain pointers to
+ // new space objects.
+ *p = MigrateObject(object, target, object_size);
#ifdef DEBUG
- VerifyNonPointerSpacePointersVisitor v;
- (*p)->Iterate(&v);
+ VerifyNonPointerSpacePointersVisitor v;
+ (*p)->Iterate(&v);
#endif
+ }
+ return;
}
- return;
}
}
-
// The object should remain in new space or the old space allocation
failed.
Object* result = new_space_.AllocateRaw(object_size);
// Failed allocation at this point is utterly unexpected.
@@ -1698,7 +1720,7 @@
}
int size = ByteArray::SizeFor(length);
AllocationSpace space =
- size > MaxHeapObjectSize() ? LO_SPACE : OLD_DATA_SPACE;
+ size > MaxObjectSizeInPagedSpace() ? LO_SPACE : OLD_DATA_SPACE;
Object* result = AllocateRaw(size, space, OLD_DATA_SPACE);
@@ -1713,7 +1735,7 @@
Object* Heap::AllocateByteArray(int length) {
int size = ByteArray::SizeFor(length);
AllocationSpace space =
- size > MaxHeapObjectSize() ? LO_SPACE : NEW_SPACE;
+ size > MaxObjectSizeInPagedSpace() ? LO_SPACE : NEW_SPACE;
Object* result = AllocateRaw(size, space, OLD_DATA_SPACE);
@@ -1748,7 +1770,7 @@
int obj_size = Code::SizeFor(body_size, sinfo_size);
ASSERT(IsAligned(obj_size, Code::kCodeAlignment));
Object* result;
- if (obj_size > MaxHeapObjectSize()) {
+ if (obj_size > MaxObjectSizeInPagedSpace()) {
result = lo_space_->AllocateRawCode(obj_size);
} else {
result = code_space_->AllocateRaw(obj_size);
@@ -1788,7 +1810,7 @@
// Allocate an object the same size as the code object.
int obj_size = code->Size();
Object* result;
- if (obj_size > MaxHeapObjectSize()) {
+ if (obj_size > MaxObjectSizeInPagedSpace()) {
result = lo_space_->AllocateRawCode(obj_size);
} else {
result = code_space_->AllocateRaw(obj_size);
@@ -1963,7 +1985,7 @@
// Allocate the JSObject.
AllocationSpace space =
(pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
- if (map->instance_size() > MaxHeapObjectSize()) space = LO_SPACE;
+ if (map->instance_size() > MaxObjectSizeInPagedSpace()) space = LO_SPACE;
Object* obj = Allocate(map, space);
if (obj->IsFailure()) return obj;
@@ -2250,7 +2272,7 @@
// Allocate string.
AllocationSpace space =
- (size > MaxHeapObjectSize()) ? LO_SPACE : OLD_DATA_SPACE;
+ (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_DATA_SPACE;
Object* result = AllocateRaw(size, space, OLD_DATA_SPACE);
if (result->IsFailure()) return result;
@@ -2272,13 +2294,16 @@
Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE :
NEW_SPACE;
int size = SeqAsciiString::SizeFor(length);
- if (size > MaxHeapObjectSize()) {
- space = LO_SPACE;
- }
- // Use AllocateRaw rather than Allocate because the object's size cannot
be
- // determined from the map.
- Object* result = AllocateRaw(size, space, OLD_DATA_SPACE);
+ Object* result = Failure::OutOfMemoryException();
+ if (space == NEW_SPACE) {
+ result = size <= kMaxObjectSizeInNewSpace
+ ? new_space_.AllocateRaw(size)
+ : lo_space_->AllocateRawFixedArray(size);
+ } else {
+ if (size > MaxObjectSizeInPagedSpace()) space = LO_SPACE;
+ result = AllocateRaw(size, space, OLD_DATA_SPACE);
+ }
if (result->IsFailure()) return result;
// Determine the map based on the string's length.
@@ -2302,13 +2327,16 @@
Object* Heap::AllocateRawTwoByteString(int length, PretenureFlag
pretenure) {
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE :
NEW_SPACE;
int size = SeqTwoByteString::SizeFor(length);
- if (size > MaxHeapObjectSize()) {
- space = LO_SPACE;
- }
- // Use AllocateRaw rather than Allocate because the object's size cannot
be
- // determined from the map.
- Object* result = AllocateRaw(size, space, OLD_DATA_SPACE);
+ Object* result = Failure::OutOfMemoryException();
+ if (space == NEW_SPACE) {
+ result = size <= kMaxObjectSizeInNewSpace
+ ? new_space_.AllocateRaw(size)
+ : lo_space_->AllocateRawFixedArray(size);
+ } else {
+ if (size > MaxObjectSizeInPagedSpace()) space = LO_SPACE;
+ result = AllocateRaw(size, space, OLD_DATA_SPACE);
+ }
if (result->IsFailure()) return result;
// Determine the map based on the string's length.
@@ -2345,9 +2373,9 @@
if (always_allocate()) return AllocateFixedArray(length, NOT_TENURED);
// Allocate the raw data for a fixed array.
int size = FixedArray::SizeFor(length);
- return (size > MaxHeapObjectSize())
- ? lo_space_->AllocateRawFixedArray(size)
- : new_space_.AllocateRaw(size);
+ return size <= kMaxObjectSizeInNewSpace
+ ? new_space_.AllocateRaw(size)
+ : lo_space_->AllocateRawFixedArray(size);
}
@@ -2395,16 +2423,22 @@
if (length == 0) return empty_fixed_array();
int size = FixedArray::SizeFor(length);
- Object* result;
- if (size > MaxHeapObjectSize()) {
- result = lo_space_->AllocateRawFixedArray(size);
- } else {
- AllocationSpace space =
- (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
- result = AllocateRaw(size, space, OLD_POINTER_SPACE);
+ Object* result = Failure::OutOfMemoryException();
+ if (pretenure != TENURED) {
+ result = size <= kMaxObjectSizeInNewSpace
+ ? new_space_.AllocateRaw(size)
+ : lo_space_->AllocateRawFixedArray(size);
+ }
+ if (result->IsFailure()) {
+ if (size > MaxObjectSizeInPagedSpace()) {
+ result = lo_space_->AllocateRawFixedArray(size);
+ } else {
+ AllocationSpace space =
+ (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
+ result = AllocateRaw(size, space, OLD_POINTER_SPACE);
+ }
+ if (result->IsFailure()) return result;
}
- if (result->IsFailure()) return result;
-
// Initialize the object.
reinterpret_cast<Array*>(result)->set_map(fixed_array_map());
FixedArray* array = FixedArray::cast(result);
@@ -2504,7 +2538,7 @@
}
int size = map->instance_size();
AllocationSpace space =
- (size > MaxHeapObjectSize()) ? LO_SPACE : OLD_POINTER_SPACE;
+ (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_POINTER_SPACE;
Object* result = Heap::Allocate(map, space);
if (result->IsFailure()) return result;
Struct::cast(result)->InitializeBody(size);
Modified: branches/bleeding_edge/src/heap.h
==============================================================================
--- branches/bleeding_edge/src/heap.h (original)
+++ branches/bleeding_edge/src/heap.h Thu Jun 18 07:06:36 2009
@@ -242,9 +242,8 @@
// all available bytes. Check MaxHeapObjectSize() instead.
static int Available();
- // Returns the maximum object size that heap supports. Objects larger
than
- // the maximum heap object size are allocated in a large object space.
- static inline int MaxHeapObjectSize();
+ // Returns the maximum object size in paged space.
+ static inline int MaxObjectSizeInPagedSpace();
// Returns of size of all objects residing in the heap.
static int SizeOfObjects();
@@ -829,6 +828,8 @@
static bool context_disposed_pending_;
static const int kMaxMapSpaceSize = 8*MB;
+
+ static const int kMaxObjectSizeInNewSpace = 256*KB;
static NewSpace new_space_;
static OldSpace* old_pointer_space_;
Modified: branches/bleeding_edge/src/ia32/builtins-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/builtins-ia32.cc (original)
+++ branches/bleeding_edge/src/ia32/builtins-ia32.cc Thu Jun 18 07:06:36
2009
@@ -113,7 +113,7 @@
// Make sure that the maximum heap object size will never cause us
// problem here, because it is always greater than the maximum
// instance size that can be represented in a byte.
- ASSERT(Heap::MaxHeapObjectSize() >= (1 << kBitsPerByte));
+ ASSERT(Heap::MaxObjectSizeInPagedSpace() >= (1 << kBitsPerByte));
ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address();
__ mov(ebx, Operand::StaticVariable(new_space_allocation_top));
@@ -175,7 +175,7 @@
// ebx: JSObject
// edi: start of next object (will be start of FixedArray)
// edx: number of elements in properties array
- ASSERT(Heap::MaxHeapObjectSize() >
+ ASSERT(Heap::MaxObjectSizeInPagedSpace() >
(FixedArray::kHeaderSize + 255*kPointerSize));
__ lea(ecx, Operand(edi, edx, times_4, FixedArray::kHeaderSize));
__ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
Modified: branches/bleeding_edge/src/mark-compact.cc
==============================================================================
--- branches/bleeding_edge/src/mark-compact.cc (original)
+++ branches/bleeding_edge/src/mark-compact.cc Thu Jun 18 07:06:36 2009
@@ -947,13 +947,18 @@
// Try to promote all objects in new space. Heap numbers and sequential
-// strings are promoted to the code space, all others to the old space.
+// strings are promoted to the code space, large objects to large object
space,
+// and all others to the old space.
inline Object* MCAllocateFromNewSpace(HeapObject* object, int object_size)
{
- OldSpace* target_space = Heap::TargetSpace(object);
- ASSERT(target_space == Heap::old_pointer_space() ||
- target_space == Heap::old_data_space());
- Object* forwarded = target_space->MCAllocateRaw(object_size);
-
+ Object* forwarded;
+ if (object_size > Heap::MaxObjectSizeInPagedSpace()) {
+ forwarded = Failure::Exception();
+ } else {
+ OldSpace* target_space = Heap::TargetSpace(object);
+ ASSERT(target_space == Heap::old_pointer_space() ||
+ target_space == Heap::old_data_space());
+ forwarded = target_space->MCAllocateRaw(object_size);
+ }
if (forwarded->IsFailure()) {
forwarded = Heap::new_space()->MCAllocateRaw(object_size);
}
Modified: branches/bleeding_edge/src/serialize.cc
==============================================================================
--- branches/bleeding_edge/src/serialize.cc (original)
+++ branches/bleeding_edge/src/serialize.cc Thu Jun 18 07:06:36 2009
@@ -1261,15 +1261,19 @@
found = Heap::InSpace(obj, s);
}
CHECK(found);
+ int size = obj->Size();
if (s == NEW_SPACE) {
- Space* space = Heap::TargetSpace(obj);
- ASSERT(space == Heap::old_pointer_space() ||
- space == Heap::old_data_space());
- s = (space == Heap::old_pointer_space()) ?
- OLD_POINTER_SPACE :
- OLD_DATA_SPACE;
+ if (size > Heap::MaxObjectSizeInPagedSpace()) {
+ s = LO_SPACE;
+ } else {
+ OldSpace* space = Heap::TargetSpace(obj);
+ ASSERT(space == Heap::old_pointer_space() ||
+ space == Heap::old_data_space());
+ s = (space == Heap::old_pointer_space()) ?
+ OLD_POINTER_SPACE :
+ OLD_DATA_SPACE;
+ }
}
- int size = obj->Size();
GCTreatment gc_treatment = DataObject;
if (obj->IsFixedArray()) gc_treatment = PointerObject;
else if (obj->IsCode()) gc_treatment = CodeObject;
Modified: branches/bleeding_edge/src/spaces.h
==============================================================================
--- branches/bleeding_edge/src/spaces.h (original)
+++ branches/bleeding_edge/src/spaces.h Thu Jun 18 07:06:36 2009
@@ -1041,7 +1041,6 @@
HeapObject* object = HeapObject::FromAddress(current_);
int size = (size_func_ == NULL) ? object->Size() : size_func_(object);
- ASSERT_OBJECT_SIZE(size);
current_ += size;
return object;
Modified: branches/bleeding_edge/test/cctest/test-heap.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-heap.cc (original)
+++ branches/bleeding_edge/test/cctest/test-heap.cc Thu Jun 18 07:06:36 2009
@@ -208,7 +208,7 @@
v8::HandleScope sc;
// check GC when heap is empty
- int free_bytes = Heap::MaxHeapObjectSize();
+ int free_bytes = Heap::MaxObjectSizeInPagedSpace();
CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
// allocate a function and keep it in global object's property
@@ -782,7 +782,7 @@
Factory::NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
// Allocate a large string (for large object space).
- int large_size = Heap::MaxHeapObjectSize() + 1;
+ int large_size = Heap::MaxObjectSizeInPagedSpace() + 1;
char* str = new char[large_size];
for (int i = 0; i < large_size - 1; ++i) str[i] = 'a';
str[large_size - 1] = '\0';
Modified: branches/bleeding_edge/test/cctest/test-mark-compact.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-mark-compact.cc (original)
+++ branches/bleeding_edge/test/cctest/test-mark-compact.cc Thu Jun 18
07:06:36 2009
@@ -86,8 +86,8 @@
v8::HandleScope sc;
// Allocate a fixed array in the new space.
- int array_size =
- (Heap::MaxHeapObjectSize() - Array::kHeaderSize) / (kPointerSize *
4);
+ int array_size = (Heap::MaxObjectSizeInPagedSpace() -
Array::kHeaderSize) /
+ (kPointerSize * 4);
Object* obj = Heap::AllocateFixedArray(array_size);
CHECK(!obj->IsFailure());
@@ -118,7 +118,8 @@
CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
// Allocate a big Fixed array in the new space.
- int size = (Heap::MaxHeapObjectSize() - Array::kHeaderSize) /
kPointerSize;
+ int size = (Heap::MaxObjectSizeInPagedSpace() - Array::kHeaderSize) /
+ kPointerSize;
Object* obj = Heap::AllocateFixedArray(size);
Handle<FixedArray> array(FixedArray::cast(obj));
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---