| OLD | NEW | 
|    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file |    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|    2 // for details. All rights reserved. Use of this source code is governed by a |    2 // for details. All rights reserved. Use of this source code is governed by a | 
|    3 // BSD-style license that can be found in the LICENSE file. |    3 // BSD-style license that can be found in the LICENSE file. | 
|    4  |    4  | 
|    5 #ifndef VM_ZONE_H_ |    5 #ifndef VM_ZONE_H_ | 
|    6 #define VM_ZONE_H_ |    6 #define VM_ZONE_H_ | 
|    7  |    7  | 
|    8 #include "platform/utils.h" |    8 #include "platform/utils.h" | 
|    9 #include "vm/allocation.h" |    9 #include "vm/allocation.h" | 
|   10 #include "vm/handles.h" |   10 #include "vm/handles.h" | 
|   11 #include "vm/memory_region.h" |   11 #include "vm/memory_region.h" | 
|   12  |   12  | 
|   13 namespace dart { |   13 namespace dart { | 
|   14  |   14  | 
|   15 // Zones support very fast allocation of small chunks of memory. The |   15 // Zones support very fast allocation of small chunks of memory. The | 
|   16 // chunks cannot be deallocated individually, but instead zones |   16 // chunks cannot be deallocated individually, but instead zones | 
|   17 // support deallocating all chunks in one fast operation. |   17 // support deallocating all chunks in one fast operation. | 
|   18  |   18  | 
|   19 class BaseZone { |   19 class Zone { | 
|   20  private: |   20  private: | 
|   21   BaseZone(); |   21   Zone(); | 
|   22   ~BaseZone();  // Delete all memory associated with the zone. |   22   ~Zone();  // Delete all memory associated with the zone. | 
|   23  |   23  | 
|   24   // Allocate an array sized to hold 'len' elements of type |   24   // Allocate an array sized to hold 'len' elements of type | 
|   25   // 'ElementType'.  Checks for integer overflow when performing the |   25   // 'ElementType'.  Checks for integer overflow when performing the | 
|   26   // size computation. |   26   // size computation. | 
|   27   template <class ElementType> |   27   template <class ElementType> | 
|   28   inline ElementType* Alloc(intptr_t len); |   28   inline ElementType* Alloc(intptr_t len); | 
|   29  |   29  | 
|   30   // Allocates an array sized to hold 'len' elements of type |   30   // Allocates an array sized to hold 'len' elements of type | 
|   31   // 'ElementType'.  The new array is initialized from the memory of |   31   // 'ElementType'.  The new array is initialized from the memory of | 
|   32   // 'old_array' up to 'old_len'. |   32   // 'old_array' up to 'old_len'. | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   96   // about the memory segmentations that constitute a zone. The entire |   96   // about the memory segmentations that constitute a zone. The entire | 
|   97   // implementation is in zone.cc. |   97   // implementation is in zone.cc. | 
|   98   class Segment; |   98   class Segment; | 
|   99  |   99  | 
|  100   // The current head segment; may be NULL. |  100   // The current head segment; may be NULL. | 
|  101   Segment* head_; |  101   Segment* head_; | 
|  102  |  102  | 
|  103   // List of large segments allocated in this zone; may be NULL. |  103   // List of large segments allocated in this zone; may be NULL. | 
|  104   Segment* large_segments_; |  104   Segment* large_segments_; | 
|  105  |  105  | 
|  106   friend class Zone; |  106   // Structure for managing handles allocation. | 
 |  107   VMHandles handles_; | 
 |  108   VMHandles* handles() { return &handles_; } | 
 |  109  | 
 |  110   friend class StackZone; | 
|  107   friend class ApiZone; |  111   friend class ApiZone; | 
|  108   template<typename T, typename B> friend class BaseGrowableArray; |  112   template<typename T, typename B> friend class BaseGrowableArray; | 
|  109   DISALLOW_COPY_AND_ASSIGN(BaseZone); |  113   DISALLOW_COPY_AND_ASSIGN(Zone); | 
|  110 }; |  114 }; | 
|  111  |  115  | 
|  112  |  116  | 
|  113 class Zone : public StackResource { |  117 class StackZone : public StackResource { | 
|  114  public: |  118  public: | 
|  115   // Create an empty zone and set is at the current zone for the Isolate. |  119   // Create an empty zone and set is at the current zone for the Isolate. | 
|  116   explicit Zone(BaseIsolate* isolate); |  120   explicit StackZone(BaseIsolate* isolate); | 
|  117  |  121  | 
|  118   // Delete all memory associated with the zone. |  122   // Delete all memory associated with the zone. | 
|  119   ~Zone(); |  123   ~StackZone(); | 
|  120  |  124  | 
|  121   // Allocates an array sized to hold 'len' elements of type |  125   // Allocates an array sized to hold 'len' elements of type | 
|  122   // 'ElementType'.  Checks for integer overflow when performing the |  126   // 'ElementType'.  Checks for integer overflow when performing the | 
|  123   // size computation. |  127   // size computation. | 
|  124   template <class ElementType> |  128   template <class ElementType> | 
|  125   ElementType* Alloc(intptr_t len) { return zone_.Alloc<ElementType>(len); } |  129   ElementType* Alloc(intptr_t len) { return zone_.Alloc<ElementType>(len); } | 
|  126  |  130  | 
|  127   // Allocates an array sized to hold 'len' elements of type |  131   // Allocates an array sized to hold 'len' elements of type | 
|  128   // 'ElementType'.  The new array is initialized from the memory of |  132   // 'ElementType'.  The new array is initialized from the memory of | 
|  129   // 'old_array' up to 'old_len'. |  133   // 'old_array' up to 'old_len'. | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|  147   intptr_t SizeInBytes() const { return zone_.SizeInBytes(); } |  151   intptr_t SizeInBytes() const { return zone_.SizeInBytes(); } | 
|  148  |  152  | 
|  149   // Make a copy of the string in the zone allocated area. |  153   // Make a copy of the string in the zone allocated area. | 
|  150   char* MakeCopyOfString(const char* str) { |  154   char* MakeCopyOfString(const char* str) { | 
|  151     return zone_.MakeCopyOfString(str); |  155     return zone_.MakeCopyOfString(str); | 
|  152   } |  156   } | 
|  153  |  157  | 
|  154   // Make a zone-allocated string based on printf format and args. |  158   // Make a zone-allocated string based on printf format and args. | 
|  155   char* PrintToString(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |  159   char* PrintToString(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); | 
|  156  |  160  | 
|  157   VMHandles* handles() { return &handles_; } |  161   // TODO(tball): remove once zone refactoring is finished. | 
 |  162   VMHandles* handles() { return zone_.handles(); } | 
|  158  |  163  | 
|  159   void VisitObjectPointers(ObjectPointerVisitor* visitor); |  164   void VisitObjectPointers(ObjectPointerVisitor* visitor); | 
|  160  |  165  | 
|  161  private: |  166  private: | 
|  162   BaseZone* GetBaseZone() { return &zone_; } |  167   Zone* GetBaseZone() { return &zone_; } | 
|  163  |  168  | 
|  164   BaseZone zone_; |  169   Zone zone_; | 
|  165  |  | 
|  166   // Structure for managing handles allocation. |  | 
|  167   VMHandles handles_; |  | 
|  168  |  170  | 
|  169   // Used for chaining zones in order to allow unwinding of stacks. |  171   // Used for chaining zones in order to allow unwinding of stacks. | 
|  170   Zone* previous_; |  172   StackZone* previous_; | 
|  171  |  173  | 
|  172   template<typename T> friend class GrowableArray; |  174   template<typename T> friend class GrowableArray; | 
|  173   template<typename T> friend class ZoneGrowableArray; |  175   template<typename T> friend class ZoneGrowableArray; | 
|  174  |  176  | 
|  175   DISALLOW_IMPLICIT_CONSTRUCTORS(Zone); |  177   DISALLOW_IMPLICIT_CONSTRUCTORS(StackZone); | 
|  176 }; |  178 }; | 
|  177  |  179  | 
|  178 inline uword BaseZone::AllocUnsafe(intptr_t size) { |  180 inline uword Zone::AllocUnsafe(intptr_t size) { | 
|  179   ASSERT(size >= 0); |  181   ASSERT(size >= 0); | 
|  180  |  182  | 
|  181   // Round up the requested size to fit the alignment. |  183   // Round up the requested size to fit the alignment. | 
|  182   if (size > (kIntptrMax - kAlignment)) { |  184   if (size > (kIntptrMax - kAlignment)) { | 
|  183     FATAL1("BaseZone::Alloc: 'size' is too large: size=%"Pd"", size); |  185     FATAL1("Zone::Alloc: 'size' is too large: size=%"Pd"", size); | 
|  184   } |  186   } | 
|  185   size = Utils::RoundUp(size, kAlignment); |  187   size = Utils::RoundUp(size, kAlignment); | 
|  186  |  188  | 
|  187   // Check if the requested size is available without expanding. |  189   // Check if the requested size is available without expanding. | 
|  188   uword result; |  190   uword result; | 
|  189   intptr_t free_size = (limit_ - position_); |  191   intptr_t free_size = (limit_ - position_); | 
|  190   if (free_size >= size) { |  192   if (free_size >= size) { | 
|  191     result = position_; |  193     result = position_; | 
|  192     position_ += size; |  194     position_ += size; | 
|  193   } else { |  195   } else { | 
|  194     result = AllocateExpand(size); |  196     result = AllocateExpand(size); | 
|  195   } |  197   } | 
|  196  |  198  | 
|  197   // Check that the result has the proper alignment and return it. |  199   // Check that the result has the proper alignment and return it. | 
|  198   ASSERT(Utils::IsAligned(result, kAlignment)); |  200   ASSERT(Utils::IsAligned(result, kAlignment)); | 
|  199   return result; |  201   return result; | 
|  200 } |  202 } | 
|  201  |  203  | 
|  202 template <class ElementType> |  204 template <class ElementType> | 
|  203 inline ElementType* BaseZone::Alloc(intptr_t len) { |  205 inline ElementType* Zone::Alloc(intptr_t len) { | 
|  204   const intptr_t element_size = sizeof(ElementType); |  206   const intptr_t element_size = sizeof(ElementType); | 
|  205   if (len > (kIntptrMax / element_size)) { |  207   if (len > (kIntptrMax / element_size)) { | 
|  206     FATAL2("BaseZone::Alloc: 'len' is too large: len=%"Pd", element_size=%"Pd, |  208     FATAL2("Zone::Alloc: 'len' is too large: len=%"Pd", element_size=%"Pd, | 
|  207            len, element_size); |  209            len, element_size); | 
|  208   } |  210   } | 
|  209   return reinterpret_cast<ElementType*>(AllocUnsafe(len * element_size)); |  211   return reinterpret_cast<ElementType*>(AllocUnsafe(len * element_size)); | 
|  210 } |  212 } | 
|  211  |  213  | 
|  212 template <class ElementType> |  214 template <class ElementType> | 
|  213 inline ElementType* BaseZone::Realloc(ElementType* old_data, |  215 inline ElementType* Zone::Realloc(ElementType* old_data, | 
|  214                                       intptr_t old_len, |  216                                       intptr_t old_len, | 
|  215                                       intptr_t new_len) { |  217                                       intptr_t new_len) { | 
|  216   ElementType* new_data = Alloc<ElementType>(new_len); |  218   ElementType* new_data = Alloc<ElementType>(new_len); | 
|  217   if (old_data != 0) { |  219   if (old_data != 0) { | 
|  218     memmove(reinterpret_cast<void*>(new_data), |  220     memmove(reinterpret_cast<void*>(new_data), | 
|  219             reinterpret_cast<void*>(old_data), |  221             reinterpret_cast<void*>(old_data), | 
|  220             Utils::Minimum(old_len * sizeof(ElementType), |  222             Utils::Minimum(old_len * sizeof(ElementType), | 
|  221                            new_len * sizeof(ElementType))); |  223                            new_len * sizeof(ElementType))); | 
|  222   } |  224   } | 
|  223   return new_data; |  225   return new_data; | 
|  224 } |  226 } | 
|  225  |  227  | 
|  226 }  // namespace dart |  228 }  // namespace dart | 
|  227  |  229  | 
|  228 #endif  // VM_ZONE_H_ |  230 #endif  // VM_ZONE_H_ | 
| OLD | NEW |