From 87ccb1d740d19cb962a30ab26984141656e4ee5e Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Fri, 27 Jan 2012 15:53:24 +0000 Subject: [PATCH] Break a circular include dependency. 1. heap-inl.h has a function Heap::_inline_get_heap_ that calls Isolate::Current() defined in isolate.h, so heap-inl.h requires isolate.h. 2. Isolate has an embedded Heap member, so isolate.h requires heap.h. 3. heap.h has inline functions functions defined that call Heap::_inline_get_heap_, so heap.h requires heap-inl.h (!). The upshot is that all three need to be included wherever one is. A simpler way is to break the cycle by moving the inlined functions in heap.h to heap-inl.h. R=vegorov@chromium.org BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/9121033 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10539 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/heap-inl.h | 89 +++++++++++++++++++++++++++++++-- src/heap.h | 130 +++++++++++++------------------------------------ 2 files changed, 121 insertions(+), 98 deletions(-) diff --git a/src/heap-inl.h b/src/heap-inl.h index 23fe3060a6..4c27095e3c 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -700,11 +700,94 @@ MaybeObject* TranscendentalCache::SubCache::Get(double input) { } -Heap* _inline_get_heap_() { - return HEAP; +AlwaysAllocateScope::AlwaysAllocateScope() { + // We shouldn't hit any nested scopes, because that requires + // non-handle code to call handle code. The code still works but + // performance will degrade, so we want to catch this situation + // in debug mode. + ASSERT(HEAP->always_allocate_scope_depth_ == 0); + HEAP->always_allocate_scope_depth_++; } +AlwaysAllocateScope::~AlwaysAllocateScope() { + HEAP->always_allocate_scope_depth_--; + ASSERT(HEAP->always_allocate_scope_depth_ == 0); +} + + +LinearAllocationScope::LinearAllocationScope() { + HEAP->linear_allocation_scope_depth_++; +} + + +LinearAllocationScope::~LinearAllocationScope() { + HEAP->linear_allocation_scope_depth_--; + ASSERT(HEAP->linear_allocation_scope_depth_ >= 0); +} + + +#ifdef DEBUG +void VerifyPointersVisitor::VisitPointers(Object** start, Object** end) { + for (Object** current = start; current < end; current++) { + if ((*current)->IsHeapObject()) { + HeapObject* object = HeapObject::cast(*current); + ASSERT(HEAP->Contains(object)); + ASSERT(object->map()->IsMap()); + } + } +} +#endif + + +double GCTracer::SizeOfHeapObjects() { + return (static_cast(HEAP->SizeOfObjects())) / MB; +} + + +#ifdef DEBUG +DisallowAllocationFailure::DisallowAllocationFailure() { + old_state_ = HEAP->disallow_allocation_failure_; + HEAP->disallow_allocation_failure_ = true; +} + + +DisallowAllocationFailure::~DisallowAllocationFailure() { + HEAP->disallow_allocation_failure_ = old_state_; +} +#endif + + +#ifdef DEBUG +AssertNoAllocation::AssertNoAllocation() { + old_state_ = HEAP->allow_allocation(false); +} + + +AssertNoAllocation::~AssertNoAllocation() { + HEAP->allow_allocation(old_state_); +} + + +DisableAssertNoAllocation::DisableAssertNoAllocation() { + old_state_ = HEAP->allow_allocation(true); +} + + +DisableAssertNoAllocation::~DisableAssertNoAllocation() { + HEAP->allow_allocation(old_state_); +} + +#else + +AssertNoAllocation::AssertNoAllocation() { } +AssertNoAllocation::~AssertNoAllocation() { } +DisableAssertNoAllocation::DisableAssertNoAllocation() { } +DisableAssertNoAllocation::~DisableAssertNoAllocation() { } + +#endif + + } } // namespace v8::internal #endif // V8_HEAP_INL_H_ diff --git a/src/heap.h b/src/heap.h index a2702d3543..e9cbb52ba9 100644 --- a/src/heap.h +++ b/src/heap.h @@ -45,12 +45,6 @@ namespace v8 { namespace internal { -// TODO(isolates): remove HEAP here -#define HEAP (_inline_get_heap_()) -class Heap; -inline Heap* _inline_get_heap_(); - - // Defines all the roots in Heap. #define STRONG_ROOT_LIST(V) \ V(Map, byte_array_map, ByteArrayMap) \ @@ -2042,32 +2036,15 @@ class HeapStats { class AlwaysAllocateScope { public: - AlwaysAllocateScope() { - // We shouldn't hit any nested scopes, because that requires - // non-handle code to call handle code. The code still works but - // performance will degrade, so we want to catch this situation - // in debug mode. - ASSERT(HEAP->always_allocate_scope_depth_ == 0); - HEAP->always_allocate_scope_depth_++; - } - - ~AlwaysAllocateScope() { - HEAP->always_allocate_scope_depth_--; - ASSERT(HEAP->always_allocate_scope_depth_ == 0); - } + inline AlwaysAllocateScope(); + inline ~AlwaysAllocateScope(); }; class LinearAllocationScope { public: - LinearAllocationScope() { - HEAP->linear_allocation_scope_depth_++; - } - - ~LinearAllocationScope() { - HEAP->linear_allocation_scope_depth_--; - ASSERT(HEAP->linear_allocation_scope_depth_ >= 0); - } + inline LinearAllocationScope(); + inline ~LinearAllocationScope(); }; @@ -2079,15 +2056,7 @@ class LinearAllocationScope { // objects in a heap space but above the allocation pointer. class VerifyPointersVisitor: public ObjectVisitor { public: - void VisitPointers(Object** start, Object** end) { - for (Object** current = start; current < end; current++) { - if ((*current)->IsHeapObject()) { - HeapObject* object = HeapObject::cast(*current); - ASSERT(HEAP->Contains(object)); - ASSERT(object->map()->IsMap()); - } - } - } + inline void VisitPointers(Object** start, Object** end); }; #endif @@ -2313,6 +2282,18 @@ class DescriptorLookupCache { }; +#ifdef DEBUG +class DisallowAllocationFailure { + public: + inline DisallowAllocationFailure(); + inline ~DisallowAllocationFailure(); + + private: + bool old_state_; +}; +#endif + + // A helper class to document/test C++ scopes where we do not // expect a GC. Usage: // @@ -2320,65 +2301,28 @@ class DescriptorLookupCache { // { AssertNoAllocation nogc; // ... // } +class AssertNoAllocation { + public: + inline AssertNoAllocation(); + inline ~AssertNoAllocation(); #ifdef DEBUG - -class DisallowAllocationFailure { - public: - DisallowAllocationFailure() { - old_state_ = HEAP->disallow_allocation_failure_; - HEAP->disallow_allocation_failure_ = true; - } - ~DisallowAllocationFailure() { - HEAP->disallow_allocation_failure_ = old_state_; - } private: bool old_state_; -}; - -class AssertNoAllocation { - public: - AssertNoAllocation() { - old_state_ = HEAP->allow_allocation(false); - } - - ~AssertNoAllocation() { - HEAP->allow_allocation(old_state_); - } - - private: - bool old_state_; -}; - -class DisableAssertNoAllocation { - public: - DisableAssertNoAllocation() { - old_state_ = HEAP->allow_allocation(true); - } - - ~DisableAssertNoAllocation() { - HEAP->allow_allocation(old_state_); - } - - private: - bool old_state_; -}; - -#else // ndef DEBUG - -class AssertNoAllocation { - public: - AssertNoAllocation() { } - ~AssertNoAllocation() { } -}; - -class DisableAssertNoAllocation { - public: - DisableAssertNoAllocation() { } - ~DisableAssertNoAllocation() { } -}; - #endif +}; + + +class DisableAssertNoAllocation { + public: + inline DisableAssertNoAllocation(); + inline ~DisableAssertNoAllocation(); + +#ifdef DEBUG + private: + bool old_state_; +#endif +}; // GCTracer collects and prints ONE line after each garbage collector // invocation IFF --trace_gc is used. @@ -2441,9 +2385,7 @@ class GCTracer BASE_EMBEDDED { const char* CollectorString(); // Returns size of object in heap (in MB). - double SizeOfHeapObjects() { - return (static_cast(HEAP->SizeOfObjects())) / MB; - } + inline double SizeOfHeapObjects(); double start_time_; // Timestamp set in the constructor. intptr_t start_size_; // Size of objects in heap set in constructor. @@ -2693,6 +2635,4 @@ class PathTracer : public ObjectVisitor { } } // namespace v8::internal -#undef HEAP - #endif // V8_HEAP_H_