| Index: src/heap/heap-inl.h
|
| diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h
|
| index bfb5498751f29cf3bd94d785473a64e598c10345..7e869f263a1be6e6f0ead788bf2ee42f4a3bccc0 100644
|
| --- a/src/heap/heap-inl.h
|
| +++ b/src/heap/heap-inl.h
|
| @@ -81,12 +81,12 @@ AllocationResult Heap::AllocateOneByteInternalizedString(
|
| // Compute map and object size.
|
| Map* map = one_byte_internalized_string_map();
|
| int size = SeqOneByteString::SizeFor(str.length());
|
| - AllocationSpace space = SelectSpace(size, TENURED);
|
| + AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
|
|
|
| // Allocate string.
|
| HeapObject* result;
|
| {
|
| - AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE);
|
| + AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
|
| if (!allocation.To(&result)) return allocation;
|
| }
|
|
|
| @@ -113,12 +113,12 @@ AllocationResult Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
|
| // Compute map and object size.
|
| Map* map = internalized_string_map();
|
| int size = SeqTwoByteString::SizeFor(str.length());
|
| - AllocationSpace space = SelectSpace(size, TENURED);
|
| + AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
|
|
|
| // Allocate string.
|
| HeapObject* result;
|
| {
|
| - AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE);
|
| + AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
|
| if (!allocation.To(&result)) return allocation;
|
| }
|
|
|
| @@ -183,8 +183,10 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationSpace space,
|
| }
|
| }
|
|
|
| - if (OLD_SPACE == space) {
|
| - allocation = old_space_->AllocateRaw(size_in_bytes);
|
| + if (OLD_POINTER_SPACE == space) {
|
| + allocation = old_pointer_space_->AllocateRaw(size_in_bytes);
|
| + } else if (OLD_DATA_SPACE == space) {
|
| + allocation = old_data_space_->AllocateRaw(size_in_bytes);
|
| } else if (CODE_SPACE == space) {
|
| if (size_in_bytes <= code_space()->AreaSize()) {
|
| allocation = code_space_->AllocateRaw(size_in_bytes);
|
| @@ -325,11 +327,23 @@ bool Heap::InToSpace(Object* object) {
|
| }
|
|
|
|
|
| -bool Heap::InOldSpace(Address address) { return old_space_->Contains(address); }
|
| +bool Heap::InOldPointerSpace(Address address) {
|
| + return old_pointer_space_->Contains(address);
|
| +}
|
|
|
|
|
| -bool Heap::InOldSpace(Object* object) {
|
| - return InOldSpace(reinterpret_cast<Address>(object));
|
| +bool Heap::InOldPointerSpace(Object* object) {
|
| + return InOldPointerSpace(reinterpret_cast<Address>(object));
|
| +}
|
| +
|
| +
|
| +bool Heap::InOldDataSpace(Address address) {
|
| + return old_data_space_->Contains(address);
|
| +}
|
| +
|
| +
|
| +bool Heap::InOldDataSpace(Object* object) {
|
| + return InOldDataSpace(reinterpret_cast<Address>(object));
|
| }
|
|
|
|
|
| @@ -361,16 +375,52 @@ void Heap::RecordWrites(Address address, int start, int len) {
|
| }
|
|
|
|
|
| +OldSpace* Heap::TargetSpace(HeapObject* object) {
|
| + InstanceType type = object->map()->instance_type();
|
| + AllocationSpace space = TargetSpaceId(type);
|
| + return (space == OLD_POINTER_SPACE) ? old_pointer_space_ : old_data_space_;
|
| +}
|
| +
|
| +
|
| +AllocationSpace Heap::TargetSpaceId(InstanceType type) {
|
| + // Heap numbers and sequential strings are promoted to old data space, all
|
| + // other object types are promoted to old pointer space. We do not use
|
| + // object->IsHeapNumber() and object->IsSeqString() because we already
|
| + // know that object has the heap object tag.
|
| +
|
| + // These objects are never allocated in new space.
|
| + DCHECK(type != MAP_TYPE);
|
| + DCHECK(type != CODE_TYPE);
|
| + DCHECK(type != ODDBALL_TYPE);
|
| + DCHECK(type != CELL_TYPE);
|
| +
|
| + if (type <= LAST_NAME_TYPE) {
|
| + if (type == SYMBOL_TYPE) return OLD_POINTER_SPACE;
|
| + DCHECK(type < FIRST_NONSTRING_TYPE);
|
| + // There are four string representations: sequential strings, external
|
| + // strings, cons strings, and sliced strings.
|
| + // Only the latter two contain non-map-word pointers to heap objects.
|
| + return ((type & kIsIndirectStringMask) == kIsIndirectStringTag)
|
| + ? OLD_POINTER_SPACE
|
| + : OLD_DATA_SPACE;
|
| + } else {
|
| + return (type <= LAST_DATA_TYPE) ? OLD_DATA_SPACE : OLD_POINTER_SPACE;
|
| + }
|
| +}
|
| +
|
| +
|
| bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) {
|
| // Object migration is governed by the following rules:
|
| //
|
| - // 1) Objects in new-space can be migrated to the old space
|
| + // 1) Objects in new-space can be migrated to one of the old spaces
|
| // that matches their target space or they stay in new-space.
|
| // 2) Objects in old-space stay in the same space when migrating.
|
| // 3) Fillers (two or more words) can migrate due to left-trimming of
|
| - // fixed arrays in new-space or old space.
|
| + // fixed arrays in new-space, old-data-space and old-pointer-space.
|
| // 4) Fillers (one word) can never migrate, they are skipped by
|
| // incremental marking explicitly to prevent invalid pattern.
|
| + // 5) Short external strings can end up in old pointer space when a cons
|
| + // string in old pointer space is made external (String::MakeExternal).
|
| //
|
| // Since this function is used for debugging only, we do not place
|
| // asserts here, but check everything explicitly.
|
| @@ -380,10 +430,12 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) {
|
| AllocationSpace src = chunk->owner()->identity();
|
| switch (src) {
|
| case NEW_SPACE:
|
| - return dst == src || dst == OLD_SPACE;
|
| - case OLD_SPACE:
|
| - return dst == src &&
|
| - (dst == OLD_SPACE || obj->IsFiller() || obj->IsExternalString());
|
| + return dst == src || dst == TargetSpaceId(type);
|
| + case OLD_POINTER_SPACE:
|
| + return dst == src && (dst == TargetSpaceId(type) || obj->IsFiller() ||
|
| + obj->IsExternalString());
|
| + case OLD_DATA_SPACE:
|
| + return dst == src && dst == TargetSpaceId(type);
|
| case CODE_SPACE:
|
| return dst == src && type == CODE_TYPE;
|
| case MAP_SPACE:
|
|
|