| OLD | NEW | 
|    1 // Copyright 2011 the V8 project authors. All rights reserved. |    1 // Copyright 2011 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 #ifndef V8_HEAP_SPACES_INL_H_ |    5 #ifndef V8_HEAP_SPACES_INL_H_ | 
|    6 #define V8_HEAP_SPACES_INL_H_ |    6 #define V8_HEAP_SPACES_INL_H_ | 
|    7  |    7  | 
|    8 #include "src/heap/spaces.h" |    8 #include "src/heap/spaces.h" | 
|    9 #include "src/heap-profiler.h" |    9 #include "src/heap-profiler.h" | 
|   10 #include "src/isolate.h" |   10 #include "src/isolate.h" | 
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  243 HeapObject* PagedSpace::AllocateLinearly(int size_in_bytes) { |  243 HeapObject* PagedSpace::AllocateLinearly(int size_in_bytes) { | 
|  244   Address current_top = allocation_info_.top(); |  244   Address current_top = allocation_info_.top(); | 
|  245   Address new_top = current_top + size_in_bytes; |  245   Address new_top = current_top + size_in_bytes; | 
|  246   if (new_top > allocation_info_.limit()) return NULL; |  246   if (new_top > allocation_info_.limit()) return NULL; | 
|  247  |  247  | 
|  248   allocation_info_.set_top(new_top); |  248   allocation_info_.set_top(new_top); | 
|  249   return HeapObject::FromAddress(current_top); |  249   return HeapObject::FromAddress(current_top); | 
|  250 } |  250 } | 
|  251  |  251  | 
|  252  |  252  | 
|  253 HeapObject* PagedSpace::AllocateLinearlyAligned(int size_in_bytes, |  253 HeapObject* PagedSpace::AllocateLinearlyAligned(int* size_in_bytes, | 
|  254                                                 AllocationAlignment alignment) { |  254                                                 AllocationAlignment alignment) { | 
|  255   Address current_top = allocation_info_.top(); |  255   Address current_top = allocation_info_.top(); | 
|  256   int alignment_size = 0; |  256   int filler_size = Heap::GetFillToAlign(current_top, alignment); | 
|  257  |  257  | 
|  258   if (alignment == kDoubleAligned && |  258   Address new_top = current_top + filler_size + *size_in_bytes; | 
|  259       (OffsetFrom(current_top) & kDoubleAlignmentMask) != 0) { |  | 
|  260     alignment_size = kPointerSize; |  | 
|  261     size_in_bytes += alignment_size; |  | 
|  262   } else if (alignment == kDoubleUnaligned && |  | 
|  263              (OffsetFrom(current_top) & kDoubleAlignmentMask) == 0) { |  | 
|  264     alignment_size = kPointerSize; |  | 
|  265     size_in_bytes += alignment_size; |  | 
|  266   } |  | 
|  267   Address new_top = current_top + size_in_bytes; |  | 
|  268   if (new_top > allocation_info_.limit()) return NULL; |  259   if (new_top > allocation_info_.limit()) return NULL; | 
|  269  |  260  | 
|  270   allocation_info_.set_top(new_top); |  261   allocation_info_.set_top(new_top); | 
|  271   if (alignment_size > 0) { |  262   if (filler_size > 0) { | 
|  272     return heap()->EnsureAligned(HeapObject::FromAddress(current_top), |  263     *size_in_bytes += filler_size; | 
|  273                                  size_in_bytes, alignment); |  264     return heap()->PrecedeWithFiller(HeapObject::FromAddress(current_top), | 
 |  265                                      filler_size); | 
|  274   } |  266   } | 
 |  267  | 
|  275   return HeapObject::FromAddress(current_top); |  268   return HeapObject::FromAddress(current_top); | 
|  276 } |  269 } | 
|  277  |  270  | 
|  278  |  271  | 
|  279 // Raw allocation. |  272 // Raw allocation. | 
|  280 AllocationResult PagedSpace::AllocateRawUnaligned(int size_in_bytes) { |  273 AllocationResult PagedSpace::AllocateRawUnaligned(int size_in_bytes) { | 
|  281   HeapObject* object = AllocateLinearly(size_in_bytes); |  274   HeapObject* object = AllocateLinearly(size_in_bytes); | 
|  282  |  275  | 
|  283   if (object == NULL) { |  276   if (object == NULL) { | 
|  284     object = free_list_.Allocate(size_in_bytes); |  277     object = free_list_.Allocate(size_in_bytes); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  296   } |  289   } | 
|  297  |  290  | 
|  298   return AllocationResult::Retry(identity()); |  291   return AllocationResult::Retry(identity()); | 
|  299 } |  292 } | 
|  300  |  293  | 
|  301  |  294  | 
|  302 // Raw allocation. |  295 // Raw allocation. | 
|  303 AllocationResult PagedSpace::AllocateRawAligned(int size_in_bytes, |  296 AllocationResult PagedSpace::AllocateRawAligned(int size_in_bytes, | 
|  304                                                 AllocationAlignment alignment) { |  297                                                 AllocationAlignment alignment) { | 
|  305   DCHECK(identity() == OLD_SPACE); |  298   DCHECK(identity() == OLD_SPACE); | 
|  306   HeapObject* object = AllocateLinearlyAligned(size_in_bytes, alignment); |  299   int allocation_size = size_in_bytes; | 
|  307   int aligned_size_in_bytes = size_in_bytes + kPointerSize; |  300   HeapObject* object = AllocateLinearlyAligned(&allocation_size, alignment); | 
|  308  |  301  | 
|  309   if (object == NULL) { |  302   if (object == NULL) { | 
|  310     object = free_list_.Allocate(aligned_size_in_bytes); |  303     // We don't know exactly how much filler we need to align until space is | 
 |  304     // allocated, so assume the worst case. | 
 |  305     int filler_size = Heap::GetMaximumFillToAlign(alignment); | 
 |  306     allocation_size += filler_size; | 
 |  307     object = free_list_.Allocate(allocation_size); | 
|  311     if (object == NULL) { |  308     if (object == NULL) { | 
|  312       object = SlowAllocateRaw(aligned_size_in_bytes); |  309       object = SlowAllocateRaw(allocation_size); | 
|  313     } |  310     } | 
|  314     if (object != NULL) { |  311     if (object != NULL && filler_size != 0) { | 
|  315       object = heap()->EnsureAligned(object, aligned_size_in_bytes, alignment); |  312       object = heap()->AlignWithFiller(object, size_in_bytes, allocation_size, | 
 |  313                                        alignment); | 
|  316     } |  314     } | 
|  317   } |  315   } | 
|  318  |  316  | 
|  319   if (object != NULL) { |  317   if (object != NULL) { | 
|  320     MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), size_in_bytes); |  318     MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), allocation_size); | 
|  321     return object; |  319     return object; | 
|  322   } |  320   } | 
|  323  |  321  | 
|  324   return AllocationResult::Retry(identity()); |  322   return AllocationResult::Retry(identity()); | 
|  325 } |  323 } | 
|  326  |  324  | 
|  327  |  325  | 
|  328 AllocationResult PagedSpace::AllocateRaw(int size_in_bytes, |  326 AllocationResult PagedSpace::AllocateRaw(int size_in_bytes, | 
|  329                                          AllocationAlignment alignment) { |  327                                          AllocationAlignment alignment) { | 
|  330 #ifdef V8_HOST_ARCH_32_BIT |  328 #ifdef V8_HOST_ARCH_32_BIT | 
|  331   return alignment == kDoubleAligned |  329   return alignment == kDoubleAligned | 
|  332              ? AllocateRawAligned(size_in_bytes, kDoubleAligned) |  330              ? AllocateRawAligned(size_in_bytes, kDoubleAligned) | 
|  333              : AllocateRawUnaligned(size_in_bytes); |  331              : AllocateRawUnaligned(size_in_bytes); | 
|  334 #else |  332 #else | 
|  335   return AllocateRawUnaligned(size_in_bytes); |  333   return AllocateRawUnaligned(size_in_bytes); | 
|  336 #endif |  334 #endif | 
|  337 } |  335 } | 
|  338  |  336  | 
|  339  |  337  | 
|  340 // ----------------------------------------------------------------------------- |  338 // ----------------------------------------------------------------------------- | 
|  341 // NewSpace |  339 // NewSpace | 
|  342  |  340  | 
|  343  |  341  | 
|  344 AllocationResult NewSpace::AllocateRawAligned(int size_in_bytes, |  342 AllocationResult NewSpace::AllocateRawAligned(int size_in_bytes, | 
|  345                                               AllocationAlignment alignment) { |  343                                               AllocationAlignment alignment) { | 
|  346   Address old_top = allocation_info_.top(); |  344   Address old_top = allocation_info_.top(); | 
|  347   int alignment_size = 0; |  345   int filler_size = Heap::GetFillToAlign(old_top, alignment); | 
|  348   int aligned_size_in_bytes = 0; |  346   int aligned_size_in_bytes = size_in_bytes + filler_size; | 
|  349  |  | 
|  350   // If double alignment is required and top pointer is not aligned, we allocate |  | 
|  351   // additional memory to take care of the alignment. |  | 
|  352   if (alignment == kDoubleAligned && |  | 
|  353       (OffsetFrom(old_top) & kDoubleAlignmentMask) != 0) { |  | 
|  354     alignment_size += kPointerSize; |  | 
|  355   } else if (alignment == kDoubleUnaligned && |  | 
|  356              (OffsetFrom(old_top) & kDoubleAlignmentMask) == 0) { |  | 
|  357     alignment_size += kPointerSize; |  | 
|  358   } |  | 
|  359   aligned_size_in_bytes = size_in_bytes + alignment_size; |  | 
|  360  |  347  | 
|  361   if (allocation_info_.limit() - old_top < aligned_size_in_bytes) { |  348   if (allocation_info_.limit() - old_top < aligned_size_in_bytes) { | 
|  362     return SlowAllocateRaw(size_in_bytes, alignment); |  349     return SlowAllocateRaw(size_in_bytes, alignment); | 
|  363   } |  350   } | 
|  364  |  351  | 
|  365   HeapObject* obj = HeapObject::FromAddress(old_top); |  352   HeapObject* obj = HeapObject::FromAddress(old_top); | 
|  366   allocation_info_.set_top(allocation_info_.top() + aligned_size_in_bytes); |  353   allocation_info_.set_top(allocation_info_.top() + aligned_size_in_bytes); | 
|  367   DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |  354   DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 
|  368  |  355  | 
|  369   if (alignment_size > 0) { |  356   if (filler_size > 0) { | 
|  370     obj = heap()->PrecedeWithFiller(obj); |  357     obj = heap()->PrecedeWithFiller(obj, filler_size); | 
|  371   } |  358   } | 
|  372  |  359  | 
|  373   // The slow path above ultimately goes through AllocateRaw, so this suffices. |  360   // The slow path above ultimately goes through AllocateRaw, so this suffices. | 
|  374   MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes); |  361   MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes); | 
|  375  |  362  | 
|  376   DCHECK((kDoubleAligned && (OffsetFrom(obj) & kDoubleAlignmentMask) == 0) || |  | 
|  377          (kDoubleUnaligned && (OffsetFrom(obj) & kDoubleAlignmentMask) != 0)); |  | 
|  378  |  | 
|  379   return obj; |  363   return obj; | 
|  380 } |  364 } | 
|  381  |  365  | 
|  382  |  366  | 
|  383 AllocationResult NewSpace::AllocateRawUnaligned(int size_in_bytes) { |  367 AllocationResult NewSpace::AllocateRawUnaligned(int size_in_bytes) { | 
|  384   Address old_top = allocation_info_.top(); |  368   Address old_top = allocation_info_.top(); | 
|  385  |  369  | 
|  386   if (allocation_info_.limit() - old_top < size_in_bytes) { |  370   if (allocation_info_.limit() - old_top < size_in_bytes) { | 
|  387     return SlowAllocateRaw(size_in_bytes, kWordAligned); |  371     return SlowAllocateRaw(size_in_bytes, kWordAligned); | 
|  388   } |  372   } | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|  417  |  401  | 
|  418  |  402  | 
|  419 intptr_t LargeObjectSpace::Available() { |  403 intptr_t LargeObjectSpace::Available() { | 
|  420   return ObjectSizeFor(heap()->isolate()->memory_allocator()->Available()); |  404   return ObjectSizeFor(heap()->isolate()->memory_allocator()->Available()); | 
|  421 } |  405 } | 
|  422  |  406  | 
|  423 } |  407 } | 
|  424 }  // namespace v8::internal |  408 }  // namespace v8::internal | 
|  425  |  409  | 
|  426 #endif  // V8_HEAP_SPACES_INL_H_ |  410 #endif  // V8_HEAP_SPACES_INL_H_ | 
| OLD | NEW |