Revision: 12746
Author:   [email protected]
Date:     Wed Oct 17 06:04:49 2012
Log:      Move DescriptorArray into the map.

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

Modified:
 /branches/bleeding_edge/src/arm/macro-assembler-arm.cc
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/heap-inl.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
 /branches/bleeding_edge/src/mips/macro-assembler-mips.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects-printer.cc
 /branches/bleeding_edge/src/objects-visiting-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/profile-generator.cc
 /branches/bleeding_edge/src/spaces.h
 /branches/bleeding_edge/src/transitions-inl.h
 /branches/bleeding_edge/src/transitions.cc
 /branches/bleeding_edge/src/transitions.h
 /branches/bleeding_edge/src/v8globals.h
 /branches/bleeding_edge/src/x64/macro-assembler-x64.cc
 /branches/bleeding_edge/test/cctest/test-alloc.cc
 /branches/bleeding_edge/test/cctest/test-heap-profiler.cc

=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Oct 15 08:19:36 2012 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Oct 17 06:04:49 2012
@@ -3742,29 +3742,7 @@
 void MacroAssembler::LoadInstanceDescriptors(Register map,
                                              Register descriptors,
                                              Register scratch) {
-  Register temp = descriptors;
-  ldr(temp, FieldMemOperand(map, Map::kTransitionsOrBackPointerOffset));
-
-  Label ok, fail, load_from_back_pointer;
-  CheckMap(temp,
-           scratch,
-           isolate()->factory()->fixed_array_map(),
-           &fail,
-           DONT_DO_SMI_CHECK);
- ldr(descriptors, FieldMemOperand(temp, TransitionArray::kDescriptorsOffset));
-  jmp(&ok);
-
-  bind(&fail);
-  CompareRoot(temp, Heap::kUndefinedValueRootIndex);
-  b(ne, &load_from_back_pointer);
-  mov(descriptors, Operand(FACTORY->empty_descriptor_array()));
-  jmp(&ok);
-
-  bind(&load_from_back_pointer);
-  ldr(temp, FieldMemOperand(temp, Map::kTransitionsOrBackPointerOffset));
- ldr(descriptors, FieldMemOperand(temp, TransitionArray::kDescriptorsOffset));
-
-  bind(&ok);
+  ldr(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset));
 }


=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Sun Oct 14 23:34:22 2012
+++ /branches/bleeding_edge/src/bootstrapper.cc Wed Oct 17 06:04:49 2012
@@ -397,7 +397,7 @@
   }
   PropertyAttributes attribs = static_cast<PropertyAttributes>(
       DONT_ENUM | DONT_DELETE | READ_ONLY);
-  Map::SetDescriptors(map, descriptors);
+  map->set_instance_descriptors(*descriptors);

   {  // Add length.
     CallbacksDescriptor d(*factory()->length_symbol(), *length, attribs);
@@ -538,7 +538,7 @@
   }
   PropertyAttributes attribs = static_cast<PropertyAttributes>(
       DONT_ENUM | DONT_DELETE);
-  Map::SetDescriptors(map, descriptors);
+  map->set_instance_descriptors(*descriptors);

   {  // Add length.
     CallbacksDescriptor d(*factory()->length_symbol(), *length, attribs);
@@ -875,7 +875,7 @@
Handle<Foreign> array_length(factory->NewForeign(&Accessors::ArrayLength));
     PropertyAttributes attribs = static_cast<PropertyAttributes>(
         DONT_ENUM | DONT_DELETE);
-    Map::SetDescriptors(initial_map, array_descriptors);
+    initial_map->set_instance_descriptors(*array_descriptors);

     {  // Add length.
CallbacksDescriptor d(*factory->length_symbol(), *array_length, attribs);
@@ -924,7 +924,7 @@
         factory->NewForeign(&Accessors::StringLength));
     PropertyAttributes attribs = static_cast<PropertyAttributes>(
         DONT_ENUM | DONT_DELETE | READ_ONLY);
-    Map::SetDescriptors(string_map, string_descriptors);
+    string_map->set_instance_descriptors(*string_descriptors);

     {  // Add length.
CallbacksDescriptor d(*factory->length_symbol(), *string_length, attribs);
@@ -960,7 +960,7 @@
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 5);
     DescriptorArray::WhitenessWitness witness(*descriptors);
-    Map::SetDescriptors(initial_map, descriptors);
+    initial_map->set_instance_descriptors(*descriptors);

     {
       // ECMA-262, section 15.10.7.1.
@@ -1144,7 +1144,7 @@
     // Create the descriptor array for the arguments object.
Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 3);
     DescriptorArray::WhitenessWitness witness(*descriptors);
-    Map::SetDescriptors(map, descriptors);
+    map->set_instance_descriptors(*descriptors);

     {  // length
       FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
@@ -1534,7 +1534,7 @@
         factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName));
     PropertyAttributes attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
-    Map::SetDescriptors(script_map, script_descriptors);
+    script_map->set_instance_descriptors(*script_descriptors);

     {
       CallbacksDescriptor d(
@@ -1675,7 +1675,7 @@
         &Accessors::ArrayLength));
     PropertyAttributes attribs = static_cast<PropertyAttributes>(
         DONT_ENUM | DONT_DELETE);
-    Map::SetDescriptors(initial_map, array_descriptors);
+    initial_map->set_instance_descriptors(*array_descriptors);

     {  // Add length.
       CallbacksDescriptor d(
@@ -1770,7 +1770,7 @@
     Handle<DescriptorArray> reresult_descriptors =
         factory()->NewDescriptorArray(0, 3);
     DescriptorArray::WhitenessWitness witness(*reresult_descriptors);
-    Map::SetDescriptors(initial_map, reresult_descriptors);
+    initial_map->set_instance_descriptors(*reresult_descriptors);

     {
       JSFunction* array_function = native_context()->array_function();
=======================================
--- /branches/bleeding_edge/src/heap-inl.h      Fri Oct 12 04:41:14 2012
+++ /branches/bleeding_edge/src/heap-inl.h      Wed Oct 17 06:04:49 2012
@@ -267,13 +267,6 @@
 #endif
   MaybeObject* result = map_space_->AllocateRaw(Map::kSize);
   if (result->IsFailure()) old_gen_exhausted_ = true;
-#ifdef DEBUG
-  if (!result->IsFailure()) {
-    // Maps have their own alignment.
-    CHECK((reinterpret_cast<intptr_t>(result) & kMapAlignmentMask) ==
-          static_cast<intptr_t>(kHeapObjectTag));
-  }
-#endif
   return result;
 }

=======================================
--- /branches/bleeding_edge/src/heap.cc Fri Oct 12 06:49:12 2012
+++ /branches/bleeding_edge/src/heap.cc Wed Oct 17 06:04:49 2012
@@ -2102,6 +2102,7 @@
   map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
   map->init_back_pointer(undefined_value());
   map->set_unused_property_fields(0);
+  map->set_instance_descriptors(empty_descriptor_array());
   map->set_bit_field(0);
   map->set_bit_field2(1 << Map::kIsExtensible);
   int bit_field3 = Map::EnumLengthBits::encode(Map::kInvalidEnumCache) |
@@ -2109,12 +2110,6 @@
   map->set_bit_field3(bit_field3);
   map->set_elements_kind(elements_kind);

-  // If the map object is aligned fill the padding area with Smi 0 objects.
-  if (Map::kPadStart < Map::kSize) {
-    memset(reinterpret_cast<byte*>(map) + Map::kPadStart - kHeapObjectTag,
-           0,
-           Map::kSize - Map::kPadStart);
-  }
   return map;
 }

@@ -2241,12 +2236,15 @@
   // Fix the instance_descriptors for the existing maps.
   meta_map()->set_code_cache(empty_fixed_array());
   meta_map()->init_back_pointer(undefined_value());
+  meta_map()->set_instance_descriptors(empty_descriptor_array());

   fixed_array_map()->set_code_cache(empty_fixed_array());
   fixed_array_map()->init_back_pointer(undefined_value());
+  fixed_array_map()->set_instance_descriptors(empty_descriptor_array());

   oddball_map()->set_code_cache(empty_fixed_array());
   oddball_map()->init_back_pointer(undefined_value());
+  oddball_map()->set_instance_descriptors(empty_descriptor_array());

   // Fix prototype object for existing maps.
   meta_map()->set_prototype(null_value());
@@ -3956,8 +3954,7 @@
       if (HasDuplicates(descriptors)) {
         fun->shared()->ForbidInlineConstructor();
       } else {
- MaybeObject* maybe_failure = map->InitializeDescriptors(descriptors);
-        if (maybe_failure->IsFailure()) return maybe_failure;
+        map->InitializeDescriptors(descriptors);
         map->set_pre_allocated_property_fields(count);
         map->set_unused_property_fields(in_object_properties - count);
       }
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Fri Oct 12 04:09:14 2012 +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Wed Oct 17 06:04:49 2012
@@ -2577,28 +2577,7 @@

 void MacroAssembler::LoadInstanceDescriptors(Register map,
                                              Register descriptors) {
-  Register temp = descriptors;
-  mov(temp, FieldOperand(map, Map::kTransitionsOrBackPointerOffset));
-
-  Label ok, fail, load_from_back_pointer;
-  CheckMap(temp,
-           isolate()->factory()->fixed_array_map(),
-           &fail,
-           DONT_DO_SMI_CHECK);
- mov(descriptors, FieldOperand(temp, TransitionArray::kDescriptorsOffset));
-  jmp(&ok);
-
-  bind(&fail);
-  cmp(temp, isolate()->factory()->undefined_value());
-  j(not_equal, &load_from_back_pointer, Label::kNear);
-  mov(descriptors, isolate()->factory()->empty_descriptor_array());
-  jmp(&ok);
-
-  bind(&load_from_back_pointer);
-  mov(temp, FieldOperand(temp, Map::kTransitionsOrBackPointerOffset));
- mov(descriptors, FieldOperand(temp, TransitionArray::kDescriptorsOffset));
-
-  bind(&ok);
+  mov(descriptors, FieldOperand(map, Map::kDescriptorsOffset));
 }


=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Tue Oct 16 01:45:17 2012 +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Wed Oct 17 06:04:49 2012
@@ -5304,29 +5304,7 @@
 void MacroAssembler::LoadInstanceDescriptors(Register map,
                                              Register descriptors,
                                              Register scratch) {
-  Register temp = descriptors;
-  lw(temp, FieldMemOperand(map, Map::kTransitionsOrBackPointerOffset));
-
-  Label ok, fail, load_from_back_pointer;
-  CheckMap(temp,
-           scratch,
-           isolate()->factory()->fixed_array_map(),
-           &fail,
-           DONT_DO_SMI_CHECK);
- lw(descriptors, FieldMemOperand(temp, TransitionArray::kDescriptorsOffset));
-  jmp(&ok);
-
-  bind(&fail);
-  LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
-  Branch(&load_from_back_pointer, ne, temp, Operand(scratch));
-  LoadRoot(descriptors, Heap::kEmptyDescriptorArrayRootIndex);
-  jmp(&ok);
-
-  bind(&load_from_back_pointer);
-  lw(temp, FieldMemOperand(temp, Map::kTransitionsOrBackPointerOffset));
- lw(descriptors, FieldMemOperand(temp, TransitionArray::kDescriptorsOffset));
-
-  bind(&ok);
+  lw(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset));
 }


=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Fri Oct 12 04:41:14 2012
+++ /branches/bleeding_edge/src/objects-inl.h   Wed Oct 17 06:04:49 2012
@@ -3548,32 +3548,16 @@
 }


-DescriptorArray* Map::instance_descriptors() {
-  if (HasTransitionArray()) return transitions()->descriptors();
-  Object* back_pointer = GetBackPointer();
-  if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array();
-  return Map::cast(back_pointer)->instance_descriptors();
-}
-
-
-enum TransitionsKind { DESCRIPTORS_HOLDER, FULL_TRANSITION_ARRAY };
-
-
// If the descriptor is using the empty transition array, install a new empty
 // transition array that will have place for an element transition.
-static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) {
+static MaybeObject* EnsureHasTransitionArray(Map* map) {
   TransitionArray* transitions;
   MaybeObject* maybe_transitions;
   if (!map->HasTransitionArray()) {
-    if (kind == FULL_TRANSITION_ARRAY) {
-      maybe_transitions = TransitionArray::Allocate(0);
-    } else {
-      maybe_transitions = TransitionArray::AllocateDescriptorsHolder();
-    }
+    maybe_transitions = TransitionArray::Allocate(0);
     if (!maybe_transitions->To(&transitions)) return maybe_transitions;
     transitions->set_back_pointer_storage(map->GetBackPointer());
-  } else if (kind == FULL_TRANSITION_ARRAY &&
-             !map->transitions()->IsFullTransitionArray()) {
+  } else if (!map->transitions()->IsFullTransitionArray()) {
     maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
     if (!maybe_transitions->To(&transitions)) return maybe_transitions;
   } else {
@@ -3584,19 +3568,7 @@
 }


-MaybeObject* Map::SetDescriptors(DescriptorArray* value) {
-  ASSERT(!is_shared());
-  MaybeObject* maybe_failure =
-      EnsureHasTransitionArray(this, DESCRIPTORS_HOLDER);
-  if (maybe_failure->IsFailure()) return maybe_failure;
-
-  ASSERT(NumberOfOwnDescriptors() <= value->number_of_descriptors());
-  transitions()->set_descriptors(value);
-  return this;
-}
-
-
-MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) {
+void Map::InitializeDescriptors(DescriptorArray* descriptors) {
   int len = descriptors->number_of_descriptors();
 #ifdef DEBUG
   ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
@@ -3615,14 +3587,12 @@
   }
 #endif

-  MaybeObject* maybe_failure = SetDescriptors(descriptors);
-  if (maybe_failure->IsFailure()) return maybe_failure;
-
+  set_instance_descriptors(descriptors);
   SetNumberOfOwnDescriptors(len);
-  return this;
 }


+ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)


@@ -3688,8 +3658,7 @@
                                 Map* target,
                                 SimpleTransitionFlag flag) {
   if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
-  return TransitionArray::NewWith(
-      flag, key, target, instance_descriptors(), GetBackPointer());
+  return TransitionArray::NewWith(flag, key, target, GetBackPointer());
 }


@@ -3704,11 +3673,8 @@


 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
-  DescriptorArray* descriptors = instance_descriptors();
-  MaybeObject* allow_elements =
-      EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY);
+  MaybeObject* allow_elements = EnsureHasTransitionArray(this);
   if (allow_elements->IsFailure()) return allow_elements;
-  transitions()->set_descriptors(descriptors);
   transitions()->set_elements_transition(transitioned_map);
   return this;
 }
@@ -3724,9 +3690,7 @@


 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
-  DescriptorArray* descriptors = instance_descriptors();
-  MaybeObject* allow_prototype =
-      EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY);
+  MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
   if (allow_prototype->IsFailure()) return allow_prototype;
 #ifdef DEBUG
   if (HasPrototypeTransitions()) {
@@ -3734,7 +3698,6 @@
     ZapPrototypeTransitions();
   }
 #endif
-  transitions()->set_descriptors(descriptors);
   transitions()->SetPrototypeTransitions(proto_transitions);
   return this;
 }
=======================================
--- /branches/bleeding_edge/src/objects-printer.cc      Wed Oct 10 05:31:50 2012
+++ /branches/bleeding_edge/src/objects-printer.cc      Wed Oct 17 06:04:49 2012
@@ -564,10 +564,9 @@
   }
   PrintF(out, " - back pointer: ");
   GetBackPointer()->ShortPrint(out);
-  PrintF(out, "\n - instance descriptors %i #%i %i: ",
+  PrintF(out, "\n - instance descriptors %i #%i: ",
          owns_descriptors(),
-         NumberOfOwnDescriptors(),
-         StoresOwnDescriptors());
+         NumberOfOwnDescriptors());
   instance_descriptors()->ShortPrint(out);
   if (HasTransitionArray()) {
     PrintF(out, "\n - transitions: ");
=======================================
--- /branches/bleeding_edge/src/objects-visiting-inl.h Fri Oct 12 06:49:12 2012 +++ /branches/bleeding_edge/src/objects-visiting-inl.h Wed Oct 17 06:04:49 2012
@@ -390,14 +390,6 @@
     Heap* heap, TransitionArray* transitions) {
   if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return;

-  // Skip recording the descriptors_pointer slot since the cell space
-  // is not compacted and descriptors are referenced through a cell.
-  Object** descriptors_slot = transitions->GetDescriptorsSlot();
-  HeapObject* descriptors = HeapObject::cast(*descriptors_slot);
-  StaticVisitor::MarkObject(heap, descriptors);
-  heap->mark_compact_collector()->RecordSlot(
-      descriptors_slot, descriptors_slot, descriptors);
-
   // Simple transitions do not have keys nor prototype transitions.
   if (transitions->IsSimpleTransition()) return;

=======================================
--- /branches/bleeding_edge/src/objects.cc      Mon Oct 15 08:23:22 2012
+++ /branches/bleeding_edge/src/objects.cc      Wed Oct 17 06:04:49 2012
@@ -1763,23 +1763,6 @@
   Map* old_map = map();
   Map* old_target = old_map->GetTransition(transition_index);
   Object* result;
-
- // To sever a transition to a map with which the descriptors are shared, the - // larger map (more descriptors) needs to store its own descriptors array. - // Both sides of the severed chain need to have their own descriptors pointer
-  // to store distinct descriptor arrays.
-
-  // If the old_target did not yet store its own descriptors, the new
- // descriptors pointer is created for the old_target by temporarily clearing
-  // the back pointer and setting its descriptor array.
-
-  // This phase is executed before creating the new map since it requires
-  // allocation that may fail.
-  if (!old_target->StoresOwnDescriptors()) {
-    DescriptorArray* old_descriptors = old_map->instance_descriptors();
- MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors);
-    if (maybe_failure->IsFailure()) return maybe_failure;
-  }

   MaybeObject* maybe_result =
       ConvertDescriptorToField(name, new_value, attributes);
@@ -1801,8 +1784,7 @@
old_target->instance_descriptors() == old_map->instance_descriptors()) { // Since the conversion above generated a new fast map with an additional // property which can be shared as well, install this descriptor pointer - // along the entire chain of smaller maps; and remove the transition array
-    // that is only in place to hold the descriptor array in the new map.
+    // along the entire chain of smaller maps.
     Map* map;
     DescriptorArray* new_descriptors = new_map->instance_descriptors();
     DescriptorArray* old_descriptors = old_map->instance_descriptors();
@@ -1810,14 +1792,11 @@
          !current->IsUndefined();
          current = map->GetBackPointer()) {
       map = Map::cast(current);
-      if (!map->HasTransitionArray()) break;
-      TransitionArray* transitions = map->transitions();
-      if (transitions->descriptors() != old_descriptors) break;
+      if (map->instance_descriptors() != old_descriptors) break;
       map->SetEnumLength(Map::kInvalidEnumCache);
-      transitions->set_descriptors(new_descriptors);
+      map->set_instance_descriptors(new_descriptors);
     }
     old_map->set_owns_descriptors(false);
-    new_map->ClearTransitions(GetHeap());
   }

   old_map->SetTransition(transition_index, new_map);
@@ -2201,7 +2180,7 @@
     new_descriptors->CopyFrom(i, *descriptors, i, witness);
   }

-  Map::SetDescriptors(map, new_descriptors);
+  map->set_instance_descriptors(*new_descriptors);
 }


@@ -4227,13 +4206,6 @@
   }
   return true;
 }
-
-
-void Map::SetDescriptors(Handle<Map> map,
-                         Handle<DescriptorArray> descriptors) {
-  Isolate* isolate = map->GetIsolate();
-  CALL_HEAP_FUNCTION_VOID(isolate, map->SetDescriptors(*descriptors));
-}


 int Map::NumberOfDescribedProperties(DescriptorFlag which,
@@ -5013,37 +4985,37 @@

     new_descriptors->Append(descriptor, witness);

- // If the source descriptors had an enum cache we copy it. This ensures that - // the maps to which we push the new descriptor array back can rely on a
-    // cache always being available once it is set. If the map has more
- // enumerated descriptors than available in the original cache, the cache
-    // will be lazily replaced by the extended cache when needed.
-    if (descriptors->HasEnumCache()) {
-      new_descriptors->CopyEnumCacheFrom(descriptors);
-    }
+    if (old_size > 0) {
+ // If the source descriptors had an enum cache we copy it. This ensures + // that the maps to which we push the new descriptor array back can rely + // on a cache always being available once it is set. If the map has more + // enumerated descriptors than available in the original cache, the cache
+      // will be lazily replaced by the extended cache when needed.
+      if (descriptors->HasEnumCache()) {
+        new_descriptors->CopyEnumCacheFrom(descriptors);
+      }

-    Map* map;
-    // Replace descriptors by new_descriptors in all maps that share it.
-    for (Object* current = GetBackPointer();
-         !current->IsUndefined();
-         current = map->GetBackPointer()) {
-      map = Map::cast(current);
-      if (!map->HasTransitionArray()) break;
-      TransitionArray* transitions = map->transitions();
-      if (transitions->descriptors() != descriptors) break;
-      transitions->set_descriptors(new_descriptors);
+      Map* map;
+      // Replace descriptors by new_descriptors in all maps that share it.
+      for (Object* current = GetBackPointer();
+           !current->IsUndefined();
+           current = map->GetBackPointer()) {
+        map = Map::cast(current);
+        if (map->instance_descriptors() != descriptors) break;
+        map->set_instance_descriptors(new_descriptors);
+      }
+
+      set_instance_descriptors(new_descriptors);
     }
-
-    transitions->set_descriptors(new_descriptors);
   }

-  set_transitions(transitions);
   result->SetBackPointer(this);
-  set_owns_descriptors(false);
-
- result->SetNumberOfOwnDescriptors(new_descriptors->number_of_descriptors());
+  result->InitializeDescriptors(new_descriptors);
   ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);

+  set_transitions(transitions);
+  set_owns_descriptors(false);
+
   return result;
 }

@@ -5058,13 +5030,7 @@
   MaybeObject* maybe_result = CopyDropDescriptors();
   if (!maybe_result->To(&result)) return maybe_result;

- // Unless we are creating a map with no descriptors and no back pointer, we
-  // insert the descriptor array locally.
-  if (!descriptors->IsEmpty()) {
-    MaybeObject* maybe_failure = result->SetDescriptors(descriptors);
-    if (maybe_failure->IsFailure()) return maybe_failure;
- result->SetNumberOfOwnDescriptors(descriptors->number_of_descriptors());
-  }
+  result->InitializeDescriptors(descriptors);

   if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
     TransitionArray* transitions;
@@ -5075,23 +5041,6 @@
MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
     if (!maybe_transitions->To(&transitions)) return maybe_transitions;

-    if (descriptors->IsEmpty()) {
-      if (owns_descriptors()) {
- // If the copied map has no added fields, and the parent map owns its
-        // descriptors, those descriptors have to be empty. In that case,
-        // transfer ownership of the descriptors to the new child.
-        ASSERT(instance_descriptors()->IsEmpty());
-        set_owns_descriptors(false);
-      } else {
- // If the parent did not own its own descriptors, it may share a larger - // descriptors array already. In that case, force a split by setting - // the descriptor array of the new map to the empty descriptor array.
-        MaybeObject* maybe_failure =
-            result->SetDescriptors(GetHeap()->empty_descriptor_array());
-        if (maybe_failure->IsFailure()) return maybe_failure;
-      }
-    }
-
     set_transitions(transitions);
     result->SetBackPointer(this);
   }
@@ -5113,7 +5062,10 @@
     ASSERT(kind != elements_kind());
   }

-  if (flag == INSERT_TRANSITION && owns_descriptors()) {
+  bool insert_transition =
+      flag == INSERT_TRANSITION && !HasElementsTransition();
+
+  if (insert_transition && owns_descriptors()) {
     // In case the map owned its own descriptors, share the descriptors and
     // transfer ownership to the new map.
     Map* new_map;
@@ -5124,8 +5076,8 @@
     if (added_elements->IsFailure()) return added_elements;

     new_map->set_elements_kind(kind);
+    new_map->InitializeDescriptors(instance_descriptors());
     new_map->SetBackPointer(this);
-    new_map->SetNumberOfOwnDescriptors(NumberOfOwnDescriptors());
     set_owns_descriptors(false);
     return new_map;
   }
@@ -5136,24 +5088,12 @@
   Map* new_map;
   MaybeObject* maybe_new_map = Copy();
   if (!maybe_new_map->To(&new_map)) return maybe_new_map;
-  ASSERT(new_map->NumberOfOwnDescriptors() == NumberOfOwnDescriptors());
+
   new_map->set_elements_kind(kind);

-  if (flag == INSERT_TRANSITION && !HasElementsTransition()) {
- // Map::Copy does not store the descriptor array in case it is empty, since
-    // it does not insert a back pointer; implicitly indicating that its
- // descriptor array is empty. Since in this case we do want to insert a back - // pointer, we have to manually set the empty descriptor array to force a
-    // split.
-    if (!new_map->StoresOwnDescriptors()) {
-      ASSERT(new_map->NumberOfOwnDescriptors() == 0);
-      MaybeObject* maybe_failure =
-          new_map->SetDescriptors(GetHeap()->empty_descriptor_array());
-      if (maybe_failure->IsFailure()) return maybe_failure;
-    }
+  if (insert_transition) {
     MaybeObject* added_elements = set_elements_transition_map(new_map);
     if (added_elements->IsFailure()) return added_elements;
-
     new_map->SetBackPointer(this);
   }

@@ -7467,14 +7407,8 @@

// Clear a possible back pointer in case the transition leads to a dead map.
 // Return true in case a back pointer has been cleared and false otherwise.
-static bool ClearBackPointer(Heap* heap,
-                             Map* target,
-                             DescriptorArray* descriptors,
-                             bool* descriptors_owner_died) {
+static bool ClearBackPointer(Heap* heap, Map* target) {
   if (Marking::MarkBitFrom(target).Get()) return false;
-  if (target->instance_descriptors() == descriptors) {
-    *descriptors_owner_died = true;
-  }
   target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
   return true;
 }
@@ -7494,13 +7428,18 @@

   int transition_index = 0;

-  DescriptorArray* descriptors = t->descriptors();
+  DescriptorArray* descriptors = instance_descriptors();
   bool descriptors_owner_died = false;

   // Compact all live descriptors to the left.
   for (int i = 0; i < t->number_of_transitions(); ++i) {
     Map* target = t->GetTarget(i);
- if (!ClearBackPointer(heap, target, descriptors, &descriptors_owner_died)) {
+    if (ClearBackPointer(heap, target)) {
+      if (target->instance_descriptors() == descriptors) {
+        descriptors_owner_died = true;
+        descriptors_owner_died = true;
+      }
+    } else {
       if (i != transition_index) {
         String* key = t->GetKey(i);
         t->SetKey(transition_index, key);
@@ -7514,10 +7453,10 @@
   }

   if (t->HasElementsTransition() &&
-      ClearBackPointer(heap,
-                       t->elements_transition(),
-                       descriptors,
-                       &descriptors_owner_died)) {
+      ClearBackPointer(heap, t->elements_transition())) {
+    if (t->elements_transition()->instance_descriptors() == descriptors) {
+      descriptors_owner_died = true;
+    }
     t->ClearElementsTransition();
   } else {
     // If there are no transitions to be cleared, return.
@@ -7533,7 +7472,7 @@
TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
     } else {
-      t->set_descriptors(heap->empty_descriptor_array());
+      ASSERT(descriptors == GetHeap()->empty_descriptor_array());
     }
   }

@@ -13015,8 +12954,7 @@

   descriptors->Sort();

-  MaybeObject* maybe_failure = new_map->InitializeDescriptors(descriptors);
-  if (maybe_failure->IsFailure()) return maybe_failure;
+  new_map->InitializeDescriptors(descriptors);
   new_map->set_unused_property_fields(unused_property_fields);

   // Transform the object.
=======================================
--- /branches/bleeding_edge/src/objects.h       Fri Oct 12 04:41:14 2012
+++ /branches/bleeding_edge/src/objects.h       Wed Oct 17 06:04:49 2012
@@ -2456,11 +2456,12 @@

 // DescriptorArrays are fixed arrays used to hold instance descriptors.
 // The format of the these objects is:
-// [0]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
+//   [0]: Number of descriptors
+// [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
 //          [0]: pointer to fixed array with enum cache
 //          [1]: either Smi(0) or pointer to fixed array with indices
-//   [1]: first key
-//   [length() - kDescriptorSize]: last key
+//   [2]: first key
+//   [2 + number of descriptors * kDescriptorSize]: start of slack
 class DescriptorArray: public FixedArray {
  public:
   // WhitenessWitness is used to prove that a descriptor array is white
@@ -4808,7 +4809,6 @@
   static bool IsValidElementsTransition(ElementsKind from_kind,
                                         ElementsKind to_kind);

-  bool StoresOwnDescriptors() { return HasTransitionArray(); }
   inline bool HasTransitionArray();
   inline bool HasElementsTransition();
   inline Map* elements_transition_map();
@@ -4856,13 +4856,8 @@
   inline JSFunction* unchecked_constructor();

   // [instance descriptors]: describes the object.
-  inline DescriptorArray* instance_descriptors();
-  MUST_USE_RESULT inline MaybeObject* SetDescriptors(
-      DescriptorArray* descriptors);
-  static void SetDescriptors(Handle<Map> map,
-                             Handle<DescriptorArray> descriptors);
-  MUST_USE_RESULT inline MaybeObject* InitializeDescriptors(
-      DescriptorArray* descriptors);
+  DECL_ACCESSORS(instance_descriptors, DescriptorArray)
+  inline void InitializeDescriptors(DescriptorArray* descriptors);

   // [stub cache]: contains stubs compiled for this map.
   DECL_ACCESSORS(code_cache, Object)
@@ -5124,11 +5119,12 @@
   // indirection.
   static const int kTransitionsOrBackPointerOffset =
       kConstructorOffset + kPointerSize;
-  static const int kCodeCacheOffset =
+  static const int kDescriptorsOffset =
       kTransitionsOrBackPointerOffset + kPointerSize;
+  static const int kCodeCacheOffset =
+      kDescriptorsOffset + kPointerSize;
   static const int kBitField3Offset = kCodeCacheOffset + kPointerSize;
-  static const int kPadStart = kBitField3Offset + kPointerSize;
-  static const int kSize = MAP_POINTER_ALIGN(kPadStart);
+  static const int kSize = kBitField3Offset + kPointerSize;

   // Layout of pointer fields. Heap iteration code relies on them
   // being continuously allocated.
=======================================
--- /branches/bleeding_edge/src/profile-generator.cc Mon Oct 15 05:36:58 2012 +++ /branches/bleeding_edge/src/profile-generator.cc Wed Oct 17 06:04:49 2012
@@ -2009,11 +2009,6 @@
                        Map::kConstructorOffset);
   if (map->HasTransitionArray()) {
     TransitionArray* transitions = map->transitions();
-    DescriptorArray* descriptors = transitions->descriptors();
-    TagObject(descriptors, "(map descriptors)");
-    SetInternalReference(transitions, entry,
-                         "descriptors", descriptors,
-                         TransitionArray::kDescriptorsOffset);

     Object* back_pointer = transitions->back_pointer_storage();
     TagObject(transitions->back_pointer_storage(), "(back pointer)");
@@ -2034,6 +2029,12 @@
                          "backpointer", back_pointer,
                          Map::kTransitionsOrBackPointerOffset);
   }
+  DescriptorArray* descriptors = map->instance_descriptors();
+  TagObject(descriptors, "(map descriptors)");
+  SetInternalReference(map, entry,
+                       "descriptors", descriptors,
+                       Map::kDescriptorsOffset);
+
   SetInternalReference(map, entry,
                        "code_cache", map->code_cache(),
                        Map::kCodeCacheOffset);
=======================================
--- /branches/bleeding_edge/src/spaces.h        Fri Oct 12 04:41:14 2012
+++ /branches/bleeding_edge/src/spaces.h        Wed Oct 17 06:04:49 2012
@@ -100,9 +100,6 @@
#define ASSERT_OBJECT_ALIGNED(address) \
   ASSERT((OffsetFrom(address) & kObjectAlignmentMask) == 0)

-#define ASSERT_MAP_ALIGNED(address) \
-  ASSERT((OffsetFrom(address) & kMapAlignmentMask) == 0)
-
#define ASSERT_OBJECT_SIZE(size) \
   ASSERT((0 < size) && (size <= Page::kMaxNonCodeHeapObjectSize))

@@ -510,7 +507,7 @@
static const size_t kHeaderSize = kWriteBarrierCounterOffset + kPointerSize;

   static const int kBodyOffset =
-    CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize));
+      CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize);

// The start offset of the object area in a page. Aligned to both maps and // code alignment to be suitable for both. Also aligned to 32 words because
=======================================
--- /branches/bleeding_edge/src/transitions-inl.h       Thu Oct 11 05:01:19 2012
+++ /branches/bleeding_edge/src/transitions-inl.h       Wed Oct 17 06:04:49 2012
@@ -82,23 +82,6 @@
   CONDITIONAL_WRITE_BARRIER(
       heap, this, kElementsTransitionOffset, transition_map, mode);
 }
-
-
-Object** TransitionArray::GetDescriptorsSlot() {
-  return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
-                              kDescriptorsOffset);
-}
-
-
-DescriptorArray* TransitionArray::descriptors() {
-  return DescriptorArray::cast(get(kDescriptorsIndex));
-}
-
-
-void TransitionArray::set_descriptors(DescriptorArray* descriptors) {
-  ASSERT(descriptors->IsDescriptorArray());
-  set(kDescriptorsIndex, descriptors);
-}


 Object* TransitionArray::back_pointer_storage() {
=======================================
--- /branches/bleeding_edge/src/transitions.cc  Thu Oct 11 05:01:19 2012
+++ /branches/bleeding_edge/src/transitions.cc  Wed Oct 17 06:04:49 2012
@@ -73,7 +73,6 @@
 MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
                                       String* key,
                                       Map* target,
-                                      DescriptorArray* descriptors,
                                       Object* back_pointer) {
   TransitionArray* result;
   MaybeObject* maybe_result;
@@ -88,14 +87,8 @@
     result->NoIncrementalWriteBarrierSet(0, key, target);
   }
   result->set_back_pointer_storage(back_pointer);
-  result->set_descriptors(descriptors);
   return result;
 }
-
-
-MaybeObject* TransitionArray::AllocateDescriptorsHolder() {
-  return AllocateRaw(kDescriptorsHolderSize);
-}


 MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
@@ -109,7 +102,6 @@
result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0);
   }

-  result->set_descriptors(descriptors());
   result->set_back_pointer_storage(back_pointer_storage());
   return result;
 }
@@ -128,8 +120,6 @@
   maybe_array = TransitionArray::Allocate(new_size);
   if (!maybe_array->To(&result)) return maybe_array;

-  result->set_descriptors(descriptors());
-
   if (HasElementsTransition()) {
     result->set_elements_transition(elements_transition());
   }
=======================================
--- /branches/bleeding_edge/src/transitions.h   Thu Oct 11 05:01:19 2012
+++ /branches/bleeding_edge/src/transitions.h   Wed Oct 17 06:04:49 2012
@@ -39,13 +39,22 @@


// TransitionArrays are fixed arrays used to hold map transitions for property,
-// constant, and element changes.
-// The format of the these objects is:
-// [0] Descriptor array
-// [1] Undefined or back pointer map
-// [2] Smi(0) or elements transition map
-// [3] Smi(0) or fixed array of prototype transitions
-// [4] First transition
+// constant, and element changes. They can either be simple transition arrays +// that store a single property transition, or a full transition array that has +// space for elements transitions, prototype transitions and multiple property +// transitons. The details related to property transitions are accessed in the +// descriptor array of the target map. In the case of a simple transition, the
+// key is also read from the descriptor array of the target map.
+//
+// The simple format of the these objects is:
+// [0] Undefined or back pointer map
+// [1] Single transition
+//
+// The full format is:
+// [0] Undefined or back pointer map
+// [1] Smi(0) or elements transition map
+// [2] Smi(0) or fixed array of prototype transitions
+// [3] First transition
 // [length() - kTransitionSize] Last transition
 class TransitionArray: public FixedArray {
  public:
@@ -71,10 +80,6 @@
   inline bool HasElementsTransition();
   inline void ClearElementsTransition();

-  inline Object** GetDescriptorsSlot();
-  inline DescriptorArray* descriptors();
-  inline void set_descriptors(DescriptorArray* descriptors);
-
   inline Object* back_pointer_storage();
   inline void set_back_pointer_storage(
       Object* back_pointer,
@@ -102,11 +107,8 @@
       SimpleTransitionFlag flag,
       String* key,
       Map* target,
-      DescriptorArray* descriptors,
       Object* back_pointer);

-  static MUST_USE_RESULT MaybeObject* AllocateDescriptorsHolder();
-
   MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray();

   // Copy the transition array, inserting a new transition.
@@ -125,7 +127,6 @@
   // Allocates a TransitionArray.
   MUST_USE_RESULT static MaybeObject* Allocate(int number_of_transitions);

-  bool IsDescriptorsHolder() { return length() == kDescriptorsHolderSize; }
   bool IsSimpleTransition() { return length() == kSimpleTransitionSize; }
   bool IsFullTransitionArray() { return length() >= kFirstIndex; }

@@ -135,24 +136,20 @@
   // Constant for denoting key was not found.
   static const int kNotFound = -1;

-  static const int kDescriptorsIndex = 0;
-  static const int kBackPointerStorageIndex = 1;
-  static const int kDescriptorsHolderSize = 2;
+  static const int kBackPointerStorageIndex = 0;

   // Layout for full transition arrays.
-  static const int kElementsTransitionIndex = 2;
-  static const int kPrototypeTransitionsIndex = 3;
-  static const int kFirstIndex = 4;
+  static const int kElementsTransitionIndex = 1;
+  static const int kPrototypeTransitionsIndex = 2;
+  static const int kFirstIndex = 3;

   // Layout for simple transition arrays.
-  static const int kSimpleTransitionTarget = 2;
-  static const int kSimpleTransitionSize = 3;
+  static const int kSimpleTransitionTarget = 1;
+  static const int kSimpleTransitionSize = 2;
   static const int kSimpleTransitionIndex = 0;
   STATIC_ASSERT(kSimpleTransitionIndex != kNotFound);

-  static const int kDescriptorsOffset = FixedArray::kHeaderSize;
-  static const int kBackPointerStorageOffset = kDescriptorsOffset +
-                                               kPointerSize;
+  static const int kBackPointerStorageOffset = FixedArray::kHeaderSize;

   // Layout for the full transition array header.
   static const int kElementsTransitionOffset = kBackPointerStorageOffset +
=======================================
--- /branches/bleeding_edge/src/v8globals.h     Mon Oct 15 08:19:36 2012
+++ /branches/bleeding_edge/src/v8globals.h     Wed Oct 17 06:04:49 2012
@@ -52,15 +52,6 @@
 const intptr_t kDoubleAlignment = 8;
 const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1;

-// Desired alignment for maps.
-#if V8_HOST_ARCH_64_BIT
-const intptr_t kMapAlignmentBits = kObjectAlignmentBits;
-#else
-const intptr_t kMapAlignmentBits = kObjectAlignmentBits + 3;
-#endif
-const intptr_t kMapAlignment = (1 << kMapAlignmentBits);
-const intptr_t kMapAlignmentMask = kMapAlignment - 1;
-
 // Desired alignment for generated code is 32 bytes (to improve cache line
 // utilization).
 const int kCodeAlignmentBits = 5;
@@ -396,10 +387,6 @@
 #define POINTER_SIZE_ALIGN(value)                               \
   (((value) + kPointerAlignmentMask) & ~kPointerAlignmentMask)

-// MAP_POINTER_ALIGN returns the value aligned as a map pointer.
-#define MAP_POINTER_ALIGN(value)                                \
-  (((value) + kMapAlignmentMask) & ~kMapAlignmentMask)
-
// CODE_POINTER_ALIGN returns the value aligned as a generated code segment.
 #define CODE_POINTER_ALIGN(value)                               \
   (((value) + kCodeAlignmentMask) & ~kCodeAlignmentMask)
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Oct 12 04:09:14 2012 +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Wed Oct 17 06:04:49 2012
@@ -2905,28 +2905,7 @@

 void MacroAssembler::LoadInstanceDescriptors(Register map,
                                              Register descriptors) {
-  Register temp = descriptors;
-  movq(temp, FieldOperand(map, Map::kTransitionsOrBackPointerOffset));
-
-  Label ok, fail, load_from_back_pointer;
-  CheckMap(temp,
-           isolate()->factory()->fixed_array_map(),
-           &fail,
-           DONT_DO_SMI_CHECK);
- movq(descriptors, FieldOperand(temp, TransitionArray::kDescriptorsOffset));
-  jmp(&ok);
-
-  bind(&fail);
-  CompareRoot(temp, Heap::kUndefinedValueRootIndex);
-  j(not_equal, &load_from_back_pointer, Label::kNear);
-  Move(descriptors, isolate()->factory()->empty_descriptor_array());
-  jmp(&ok);
-
-  bind(&load_from_back_pointer);
-  movq(temp, FieldOperand(temp, Map::kTransitionsOrBackPointerOffset));
- movq(descriptors, FieldOperand(temp, TransitionArray::kDescriptorsOffset));
-
-  bind(&ok);
+  movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset));
 }


=======================================
--- /branches/bleeding_edge/test/cctest/test-alloc.cc Tue Sep 18 06:25:12 2012 +++ /branches/bleeding_edge/test/cctest/test-alloc.cc Wed Oct 17 06:04:49 2012
@@ -158,7 +158,7 @@
Handle<DescriptorArray> new_descriptors = FACTORY->NewDescriptorArray(0, 1);

v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors);
-  v8::internal::Map::SetDescriptors(map, new_descriptors);
+  map->set_instance_descriptors(*new_descriptors);

   CallbacksDescriptor d(*name,
                         *foreign,
=======================================
--- /branches/bleeding_edge/test/cctest/test-heap-profiler.cc Wed Sep 12 09:43:57 2012 +++ /branches/bleeding_edge/test/cctest/test-heap-profiler.cc Wed Oct 17 06:04:49 2012
@@ -1676,18 +1676,8 @@
   CHECK_NE(NULL, map);
   const v8::HeapGraphNode* own_descriptors = GetProperty(
       map, v8::HeapGraphEdge::kInternal, "descriptors");
-  CHECK_EQ(NULL, own_descriptors);
+  CHECK_NE(NULL, own_descriptors);
   const v8::HeapGraphNode* own_transitions = GetProperty(
       map, v8::HeapGraphEdge::kInternal, "transitions");
   CHECK_EQ(NULL, own_transitions);
-
-  const v8::HeapGraphNode* back_pointer_map =
-      GetProperty(map, v8::HeapGraphEdge::kInternal, "backpointer");
-  CHECK_NE(NULL, back_pointer_map);
-  const v8::HeapGraphNode* descriptors = GetProperty(
-      back_pointer_map, v8::HeapGraphEdge::kInternal, "descriptors");
-  CHECK_NE(NULL, descriptors);
-  const v8::HeapGraphNode* transitions = GetProperty(
-      back_pointer_map, v8::HeapGraphEdge::kInternal, "transitions");
-  CHECK_NE(NULL, transitions);
 }

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

Reply via email to