Move DescriptorArray into the map.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 17 Oct 2012 13:04:49 +0000 (13:04 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 17 Oct 2012 13:04:49 +0000 (13:04 +0000)
Review URL: https://chromiumcodereview.appspot.com/11188031

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12746 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

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

index 31915a5194d2c14b29ea940c859248d6342c18af..4409e2643afa32b79a7c0d309f3a4d22f1a7d4a1 100644 (file)
@@ -3742,29 +3742,7 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
 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));
 }
 
 
index 4b40d92c35757e22881ac2186eff12819a12c9b5..a368eefe766985547d2e2f8cbe37a07dff4418dd 100644 (file)
@@ -397,7 +397,7 @@ void Genesis::SetFunctionInstanceDescriptor(
   }
   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 @@ void Genesis::SetStrictFunctionInstanceDescriptor(
   }
   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 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
     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 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
         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 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
         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 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
     // 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 @@ bool Genesis::InstallNatives() {
         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 @@ bool Genesis::InstallNatives() {
         &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 @@ bool Genesis::InstallNatives() {
     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();
index 876d8d83349081501989392cbed45dfbf2f5ef0a..a7645e25f1ebf512c306dc6120f5b179f5a3dc01 100644 (file)
@@ -267,13 +267,6 @@ MaybeObject* Heap::AllocateRawMap() {
 #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;
 }
 
index 5de06aa607e76438bb795ceb8507f272714cf943..4fd1a041eabfc73b4fa6ed112c0970447e163c06 100644 (file)
@@ -2102,6 +2102,7 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type,
   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 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type,
   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 @@ bool Heap::CreateInitialMaps() {
   // 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 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
       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);
       }
index 1a64c45369572fcff233ea8c1fbee391e35ddc0e..c17a466d4243302120a3c5d718a72e05a5041fc5 100644 (file)
@@ -2577,28 +2577,7 @@ void MacroAssembler::Abort(const char* msg) {
 
 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));
 }
 
 
index 489eeb05fc492efd32889ffae381daae32d6d629..dacfc0ed5c8a74b6bc40142f2b48cf10374b0f8e 100644 (file)
@@ -5304,29 +5304,7 @@ void MacroAssembler::EnsureNotWhite(
 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));
 }
 
 
index 7e0ba9f1000a7246277e82bf52ff2ae2e0be0668..e769c15e891fd65fb3865bcc3130cb4abe2936b0 100644 (file)
@@ -3548,32 +3548,16 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) {
 }
 
 
-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 @@ static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) {
 }
 
 
-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 @@ MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) {
   }
 #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 @@ MaybeObject* Map::AddTransition(String* key,
                                 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 @@ Map* Map::GetTransition(int transition_index) {
 
 
 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 @@ FixedArray* Map::GetPrototypeTransitions() {
 
 
 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 @@ MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
     ZapPrototypeTransitions();
   }
 #endif
-  transitions()->set_descriptors(descriptors);
   transitions()->SetPrototypeTransitions(proto_transitions);
   return this;
 }
index d7727c1e94b95a22bf44bed9a884d8126b660f59..b1118de9c476f91f9b706059c516d66b81f7f1f3 100644 (file)
@@ -564,10 +564,9 @@ void Map::MapPrint(FILE* out) {
   }
   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: ");
index b704c1f3723b6f009c3e4ed7e2d82585c2d18afa..d698a8df06f95a548b8da3b246f78a62cd3ddc01 100644 (file)
@@ -390,14 +390,6 @@ void StaticMarkingVisitor<StaticVisitor>::MarkTransitionArray(
     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;
 
index 250e009b24f12c24582900bb2a4bcd89b77ab349..c9e34d587d23cdca1ed3e7fd8bb1a7861ddea4d8 100644 (file)
@@ -1764,23 +1764,6 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
   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);
   if (!maybe_result->To(&result)) return maybe_result;
@@ -1801,8 +1784,7 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
       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 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
          !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 @@ void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
     new_descriptors->CopyFrom(i, *descriptors, i, witness);
   }
 
-  Map::SetDescriptors(map, new_descriptors);
+  map->set_instance_descriptors(*new_descriptors);
 }
 
 
@@ -4229,13 +4208,6 @@ bool JSReceiver::IsSimpleEnum() {
 }
 
 
-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,
                                      PropertyAttributes filter) {
   int result = 0;
@@ -5013,37 +4985,37 @@ MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors,
 
     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);
+      }
 
-    transitions->set_descriptors(new_descriptors);
+      set_instance_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* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
   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* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
     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 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
     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 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
     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 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
   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 @@ static void TrimDescriptorArray(Heap* heap,
 
 // 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 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
 
   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 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
   }
 
   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 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
       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 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
 
   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.
index edc85dee0e5c54803432c8e8696c89cc3b2da3f5..91cafddcdcfcb926c44f69ea9261b49f6cd5c413 100644 (file)
@@ -2456,11 +2456,12 @@ class FixedDoubleArray: public FixedArrayBase {
 
 // 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 @@ class Map: public HeapObject {
   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 @@ class Map: public HeapObject {
   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 @@ class Map: public HeapObject {
   // 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.
index d9259c8c25ee294d828ea6134d8eeb5fc3a049f0..b853f33cb19aa2a15405cbdca4f76fdf3d25382b 100644 (file)
@@ -2009,11 +2009,6 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
                        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 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
                          "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);
index 7ed0977e02502279456b927cca15ee7678b8d626..95c63d6b610d2e51ef00a01e78c71b4a2766bd38 100644 (file)
@@ -100,9 +100,6 @@ class Isolate;
 #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 @@ class MemoryChunk {
   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
index 95a400e52ac8071699b7e305f4360ed3ce02e404..2df30028317e0c64e71c7f8edfc39e706cbd4339 100644 (file)
@@ -84,23 +84,6 @@ void TransitionArray::set_elements_transition(Map* transition_map,
 }
 
 
-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() {
   return get(kBackPointerStorageIndex);
 }
index a65f3c3b2a8aaf7baa9371ecbe84bf4cf423480b..56b6caf3db0a433e60c6850b41b73afbf6b6c080 100644 (file)
@@ -73,7 +73,6 @@ static bool InsertionPointFound(String* key1, String* key2) {
 MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
                                       String* key,
                                       Map* target,
-                                      DescriptorArray* descriptors,
                                       Object* back_pointer) {
   TransitionArray* result;
   MaybeObject* maybe_result;
@@ -88,16 +87,10 @@ MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
     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() {
   ASSERT(!IsFullTransitionArray());
   int nof = number_of_transitions();
@@ -109,7 +102,6 @@ MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
     result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0);
   }
 
-  result->set_descriptors(descriptors());
   result->set_back_pointer_storage(back_pointer_storage());
   return result;
 }
@@ -128,8 +120,6 @@ MaybeObject* TransitionArray::CopyInsert(String* name, Map* target) {
   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());
   }
index 9643a61812b8feca8bfdc8b9dccc7fe1acc8dc72..0a660261c58735e2fe8511e2ff8903caf919bdd5 100644 (file)
@@ -39,13 +39,22 @@ namespace internal {
 
 
 // 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 @@ class TransitionArray: public FixedArray {
   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 @@ class TransitionArray: public FixedArray {
       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 @@ class TransitionArray: public FixedArray {
   // 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 @@ class TransitionArray: public FixedArray {
   // 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 +
index 37c4c65a873b0e7910d2df36f8650cf8607ca178..648413fed2107b61b130264390b6f215c686bb8b 100644 (file)
@@ -52,15 +52,6 @@ const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
 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 @@ enum StateTag {
 #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)
index 49849d8c493e617a172ee7d122895ff8c5686c60..ee0635f91fa3352bb54d7e0c8e4c3efb8e2dc33a 100644 (file)
@@ -2905,28 +2905,7 @@ void MacroAssembler::LoadUint32(XMMRegister dst,
 
 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));
 }
 
 
index 24c7f1fdccc9386d3aac109cfde5f98deb0ab6ff..7ba2583da584023d9fe2c9e06ebf9999c80482ac 100644 (file)
@@ -158,7 +158,7 @@ TEST(StressJS) {
   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,
index 4f7421be83a37d0987e7f0e75bd66d392c5ce93b..52359711d16900de07c8e4bc07894b7518dc1869 100644 (file)
@@ -1676,18 +1676,8 @@ TEST(MapHasDescriptorsAndTransitions) {
   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);
 }