Revision: 12196
Author:   [email protected]
Date:     Thu Jul 26 01:27:20 2012
Log: Limited the size of transition arrays so they never end up in the large object space.

Also renamed SizeOf on DescriptorArray to LengthOf for consistency.

Review URL: https://chromiumcodereview.appspot.com/10822011
http://code.google.com/p/v8/source/detail?r=12196

Modified:
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Thu Jul 19 11:58:23 2012
+++ /branches/bleeding_edge/src/objects-inl.h   Thu Jul 26 01:27:20 2012
@@ -3580,6 +3580,14 @@
 Map* Map::elements_transition_map() {
   return transitions()->elements_transition();
 }
+
+
+bool Map::CanHaveMoreTransitions() {
+  if (!HasTransitionArray()) return true;
+  return FixedArray::SizeFor(transitions()->length() +
+                             TransitionArray::kTransitionSize)
+      <= Page::kMaxNonCodeHeapObjectSize;
+}


 MaybeObject* Map::AddTransition(String* key, Map* target) {
=======================================
--- /branches/bleeding_edge/src/objects.cc      Wed Jul 25 08:23:07 2012
+++ /branches/bleeding_edge/src/objects.cc      Thu Jul 26 01:27:20 2012
@@ -2120,8 +2120,6 @@
static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
   ASSERT(elms->map() != HEAP->fixed_cow_array_map());
// For now this trick is only applied to fixed arrays in new and paged space.
-  // In large object space the object's start must coincide with chunk
-  // and thus the trick is just not applicable.
   ASSERT(!HEAP->lo_space()->Contains(elms));

   const int len = elms->length();
@@ -2217,7 +2215,7 @@
   }

// If duplicates were detected, trim the descriptor array to the right size.
-  int new_array_size = DescriptorArray::SizeFor(new_number_of_descriptors);
+ int new_array_size = DescriptorArray::LengthFor(new_number_of_descriptors);
   if (new_array_size < result->length()) {
     RightTrimFixedArray<FROM_MUTATOR>(
         isolate->heap(), *result, result->length() - new_array_size);
@@ -4883,7 +4881,7 @@
     result->SetLastAdded(last_added);
   }

-  if (flag == INSERT_TRANSITION) {
+  if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
     TransitionArray* transitions;
     MaybeObject* maybe_transitions = AddTransition(name, result);
     if (!maybe_transitions->To(&transitions)) return maybe_transitions;
@@ -5843,7 +5841,7 @@
   }
   // Allocate the array of keys.
   MaybeObject* maybe_array =
-      heap->AllocateFixedArray(SizeFor(number_of_descriptors));
+      heap->AllocateFixedArray(LengthFor(number_of_descriptors));
   if (!maybe_array->To(&result)) return maybe_array;

   result->set(kEnumCacheIndex, Smi::FromInt(0));
=======================================
--- /branches/bleeding_edge/src/objects.h       Wed Jul 25 08:23:07 2012
+++ /branches/bleeding_edge/src/objects.h       Thu Jul 26 01:27:20 2012
@@ -2635,7 +2635,9 @@
   // fit in a page).
   static const int kMaxNumberOfDescriptors = 1024 + 512;

-  static int SizeFor(int number_of_descriptors) {
+  // Returns the fixed array length required to hold number_of_descriptors
+  // descriptors.
+  static int LengthFor(int number_of_descriptors) {
     return ToKeyIndex(number_of_descriptors);
   }

@@ -4896,6 +4898,11 @@
                         String* name,
                         LookupResult* result);

+ // The size of transition arrays are limited so they do not end up in large + // object space. Otherwise ClearNonLiveTransitions would leak memory while
+  // applying in-place right trimming.
+  inline bool CanHaveMoreTransitions();
+
   void SetLastAdded(int index) {
     set_bit_field3(LastAddedBits::update(bit_field3(), index));
   }

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to