| Index: src/heap-inl.h
|
| diff --git a/src/heap-inl.h b/src/heap-inl.h
|
| index 64125bc302c7d275133974a54f0566eb0126c916..df8b211fb6df5ba7d999725d69ec8c3ae54c1869 100644
|
| --- a/src/heap-inl.h
|
| +++ b/src/heap-inl.h
|
| @@ -7,6 +7,7 @@
|
|
|
| #include <cmath>
|
|
|
| +#include "src/cpu-profiler.h"
|
| #include "src/heap.h"
|
| #include "src/heap-profiler.h"
|
| #include "src/isolate.h"
|
| @@ -184,7 +185,6 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes,
|
| ASSERT(AllowHandleAllocation::IsAllowed());
|
| ASSERT(AllowHeapAllocation::IsAllowed());
|
| ASSERT(gc_state_ == NOT_IN_GC);
|
| - HeapProfiler* profiler = isolate_->heap_profiler();
|
| #ifdef DEBUG
|
| if (FLAG_gc_interval >= 0 &&
|
| AllowAllocationFailure::IsAllowed(isolate_) &&
|
| @@ -204,8 +204,8 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes,
|
| retry_space != NEW_SPACE) {
|
| space = retry_space;
|
| } else {
|
| - if (profiler->is_tracking_allocations() && allocation.To(&object)) {
|
| - profiler->AllocationEvent(object->address(), size_in_bytes);
|
| + if (allocation.To(&object)) {
|
| + OnAllocationEvent(object, size_in_bytes);
|
| }
|
| return allocation;
|
| }
|
| @@ -216,7 +216,12 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes,
|
| } else if (OLD_DATA_SPACE == space) {
|
| allocation = old_data_space_->AllocateRaw(size_in_bytes);
|
| } else if (CODE_SPACE == space) {
|
| - allocation = code_space_->AllocateRaw(size_in_bytes);
|
| + if (size_in_bytes <= code_space()->AreaSize()) {
|
| + allocation = code_space_->AllocateRaw(size_in_bytes);
|
| + } else {
|
| + // Large code objects are allocated in large object space.
|
| + allocation = lo_space_->AllocateRaw(size_in_bytes, EXECUTABLE);
|
| + }
|
| } else if (LO_SPACE == space) {
|
| allocation = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
|
| } else if (CELL_SPACE == space) {
|
| @@ -227,14 +232,99 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes,
|
| ASSERT(MAP_SPACE == space);
|
| allocation = map_space_->AllocateRaw(size_in_bytes);
|
| }
|
| - if (allocation.IsRetry()) old_gen_exhausted_ = true;
|
| - if (profiler->is_tracking_allocations() && allocation.To(&object)) {
|
| - profiler->AllocationEvent(object->address(), size_in_bytes);
|
| + if (allocation.To(&object)) {
|
| + OnAllocationEvent(object, size_in_bytes);
|
| + } else {
|
| + old_gen_exhausted_ = true;
|
| }
|
| return allocation;
|
| }
|
|
|
|
|
| +void Heap::OnAllocationEvent(HeapObject* object, int size_in_bytes) {
|
| + HeapProfiler* profiler = isolate_->heap_profiler();
|
| + if (profiler->is_tracking_allocations()) {
|
| + profiler->AllocationEvent(object->address(), size_in_bytes);
|
| + }
|
| +
|
| + if (FLAG_verify_predictable) {
|
| + ++allocations_count_;
|
| +
|
| + UpdateAllocationsHash(object);
|
| + UpdateAllocationsHash(size_in_bytes);
|
| +
|
| + if ((FLAG_dump_allocations_digest_at_alloc > 0) &&
|
| + (--dump_allocations_hash_countdown_ == 0)) {
|
| + dump_allocations_hash_countdown_ = FLAG_dump_allocations_digest_at_alloc;
|
| + PrintAlloctionsHash();
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void Heap::OnMoveEvent(HeapObject* target,
|
| + HeapObject* source,
|
| + int size_in_bytes) {
|
| + HeapProfiler* heap_profiler = isolate_->heap_profiler();
|
| + if (heap_profiler->is_tracking_object_moves()) {
|
| + heap_profiler->ObjectMoveEvent(source->address(), target->address(),
|
| + size_in_bytes);
|
| + }
|
| +
|
| + if (isolate_->logger()->is_logging_code_events() ||
|
| + isolate_->cpu_profiler()->is_profiling()) {
|
| + if (target->IsSharedFunctionInfo()) {
|
| + PROFILE(isolate_, SharedFunctionInfoMoveEvent(
|
| + source->address(), target->address()));
|
| + }
|
| + }
|
| +
|
| + if (FLAG_verify_predictable) {
|
| + ++allocations_count_;
|
| +
|
| + UpdateAllocationsHash(source);
|
| + UpdateAllocationsHash(target);
|
| + UpdateAllocationsHash(size_in_bytes);
|
| +
|
| + if ((FLAG_dump_allocations_digest_at_alloc > 0) &&
|
| + (--dump_allocations_hash_countdown_ == 0)) {
|
| + dump_allocations_hash_countdown_ = FLAG_dump_allocations_digest_at_alloc;
|
| + PrintAlloctionsHash();
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void Heap::UpdateAllocationsHash(HeapObject* object) {
|
| + Address object_address = object->address();
|
| + MemoryChunk* memory_chunk = MemoryChunk::FromAddress(object_address);
|
| + AllocationSpace allocation_space = memory_chunk->owner()->identity();
|
| +
|
| + STATIC_ASSERT(kSpaceTagSize + kPageSizeBits <= 32);
|
| + uint32_t value =
|
| + static_cast<uint32_t>(object_address - memory_chunk->address()) |
|
| + (static_cast<uint32_t>(allocation_space) << kPageSizeBits);
|
| +
|
| + UpdateAllocationsHash(value);
|
| +}
|
| +
|
| +
|
| +void Heap::UpdateAllocationsHash(uint32_t value) {
|
| + uint16_t c1 = static_cast<uint16_t>(value);
|
| + uint16_t c2 = static_cast<uint16_t>(value >> 16);
|
| + raw_allocations_hash_ =
|
| + StringHasher::AddCharacterCore(raw_allocations_hash_, c1);
|
| + raw_allocations_hash_ =
|
| + StringHasher::AddCharacterCore(raw_allocations_hash_, c2);
|
| +}
|
| +
|
| +
|
| +void Heap::PrintAlloctionsHash() {
|
| + uint32_t hash = StringHasher::GetHashCore(raw_allocations_hash_);
|
| + PrintF("\n### Allocations = %u, hash = 0x%08x\n", allocations_count_, hash);
|
| +}
|
| +
|
| +
|
| void Heap::FinalizeExternalString(String* string) {
|
| ASSERT(string->IsExternalString());
|
| v8::String::ExternalStringResourceBase** resource_addr =
|
|
|