Bug 1052582 Part 2 - Add dedicated AllocKinds just for ArrayBufferObjects. r?sfink draft
authorMatt Howell <mhowell@mozilla.com>
Tue, 22 May 2018 16:11:58 -0700
changeset 815096 4ececa06c7c43fc212063916ae72c1190f4a1219
parent 815089 91340d9e5fee5cab14fe72c1a280b63b3421c2f0
child 815097 52f7eb355590e6932cfa20ab7d7cabab09234c96
push id115434
push usermhowell@mozilla.com
push dateFri, 06 Jul 2018 17:52:20 +0000
reviewerssfink
bugs1052582
milestone63.0a1
Bug 1052582 Part 2 - Add dedicated AllocKinds just for ArrayBufferObjects. r?sfink The reason for doing this is to get ArrayBufferObjects allocated into their own arenas. The specific enum values were chosen to avoid breaking assumptions about where certain values fall in the list, such as OBJECT_FIRST == FUNCTION. MozReview-Commit-ID: KcM53eMheU7
js/src/gc/AllocKind.h
js/src/gc/GC.cpp
js/src/gc/GCRuntime.h
js/src/gc/ObjectKind-inl.h
js/src/vm/ArrayBufferObject.cpp
--- a/js/src/gc/AllocKind.h
+++ b/js/src/gc/AllocKind.h
@@ -38,22 +38,26 @@ namespace gc {
 #define FOR_EACH_OBJECT_ALLOCKIND(D) \
  /* AllocKind              TraceKind     TypeName           SizedType          BGFinal Nursery */ \
     D(FUNCTION,            Object,       JSObject,          JSFunction,        true,   true)  \
     D(FUNCTION_EXTENDED,   Object,       JSObject,          FunctionExtended,  true,   true)  \
     D(OBJECT0,             Object,       JSObject,          JSObject_Slots0,   false,  false) \
     D(OBJECT0_BACKGROUND,  Object,       JSObject,          JSObject_Slots0,   true,   true)  \
     D(OBJECT2,             Object,       JSObject,          JSObject_Slots2,   false,  false) \
     D(OBJECT2_BACKGROUND,  Object,       JSObject,          JSObject_Slots2,   true,   true)  \
+    D(ARRAYBUFFER4,        Object,       JSObject,          JSObject_Slots4,   true,   true)  \
     D(OBJECT4,             Object,       JSObject,          JSObject_Slots4,   false,  false) \
     D(OBJECT4_BACKGROUND,  Object,       JSObject,          JSObject_Slots4,   true,   true)  \
+    D(ARRAYBUFFER8,        Object,       JSObject,          JSObject_Slots8,   true,   true)  \
     D(OBJECT8,             Object,       JSObject,          JSObject_Slots8,   false,  false) \
     D(OBJECT8_BACKGROUND,  Object,       JSObject,          JSObject_Slots8,   true,   true)  \
+    D(ARRAYBUFFER12,       Object,       JSObject,          JSObject_Slots12,  true,   true)  \
     D(OBJECT12,            Object,       JSObject,          JSObject_Slots12,  false,  false) \
     D(OBJECT12_BACKGROUND, Object,       JSObject,          JSObject_Slots12,  true,   true)  \
+    D(ARRAYBUFFER16,       Object,       JSObject,          JSObject_Slots16,  true,   true)  \
     D(OBJECT16,            Object,       JSObject,          JSObject_Slots16,  false,  false) \
     D(OBJECT16_BACKGROUND, Object,       JSObject,          JSObject_Slots16,  true,   true)
 
 #define FOR_EACH_NONOBJECT_NONNURSERY_ALLOCKIND(D) \
  /* AllocKind              TraceKind     TypeName           SizedType          BGFinal Nursery */ \
     D(SCRIPT,              Script,       JSScript,          JSScript,          false,  false) \
     D(LAZY_SCRIPT,         LazyScript,   js::LazyScript,    js::LazyScript,    true,   false) \
     D(SHAPE,               Shape,        js::Shape,         js::Shape,         true,   false) \
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -473,19 +473,23 @@ static const FinalizePhase BackgroundFin
         }
     },
     {
         gcstats::PhaseKind::SWEEP_OBJECT, {
             AllocKind::FUNCTION,
             AllocKind::FUNCTION_EXTENDED,
             AllocKind::OBJECT0_BACKGROUND,
             AllocKind::OBJECT2_BACKGROUND,
+            AllocKind::ARRAYBUFFER4,
             AllocKind::OBJECT4_BACKGROUND,
+            AllocKind::ARRAYBUFFER8,
             AllocKind::OBJECT8_BACKGROUND,
+            AllocKind::ARRAYBUFFER12,
             AllocKind::OBJECT12_BACKGROUND,
+            AllocKind::ARRAYBUFFER16,
             AllocKind::OBJECT16_BACKGROUND
         }
     },
     {
         gcstats::PhaseKind::SWEEP_SCOPE, {
             AllocKind::SCOPE,
         }
     },
@@ -2176,22 +2180,26 @@ CanRelocateZone(Zone* zone)
 
 static const AllocKind AllocKindsToRelocate[] = {
     AllocKind::FUNCTION,
     AllocKind::FUNCTION_EXTENDED,
     AllocKind::OBJECT0,
     AllocKind::OBJECT0_BACKGROUND,
     AllocKind::OBJECT2,
     AllocKind::OBJECT2_BACKGROUND,
+    AllocKind::ARRAYBUFFER4,
     AllocKind::OBJECT4,
     AllocKind::OBJECT4_BACKGROUND,
+    AllocKind::ARRAYBUFFER8,
     AllocKind::OBJECT8,
     AllocKind::OBJECT8_BACKGROUND,
+    AllocKind::ARRAYBUFFER12,
     AllocKind::OBJECT12,
     AllocKind::OBJECT12_BACKGROUND,
+    AllocKind::ARRAYBUFFER16,
     AllocKind::OBJECT16,
     AllocKind::OBJECT16_BACKGROUND,
     AllocKind::SCRIPT,
     AllocKind::LAZY_SCRIPT,
     AllocKind::SHAPE,
     AllocKind::ACCESSOR_SHAPE,
     AllocKind::BASE_SHAPE,
     AllocKind::FAT_INLINE_STRING,
@@ -2891,22 +2899,26 @@ static const AllocKinds UpdatePhaseOne {
 static const AllocKinds UpdatePhaseThree {
     AllocKind::LAZY_SCRIPT,
     AllocKind::FUNCTION,
     AllocKind::FUNCTION_EXTENDED,
     AllocKind::OBJECT0,
     AllocKind::OBJECT0_BACKGROUND,
     AllocKind::OBJECT2,
     AllocKind::OBJECT2_BACKGROUND,
+    AllocKind::ARRAYBUFFER4,
     AllocKind::OBJECT4,
     AllocKind::OBJECT4_BACKGROUND,
+    AllocKind::ARRAYBUFFER8,
     AllocKind::OBJECT8,
     AllocKind::OBJECT8_BACKGROUND,
+    AllocKind::ARRAYBUFFER12,
     AllocKind::OBJECT12,
     AllocKind::OBJECT12_BACKGROUND,
+    AllocKind::ARRAYBUFFER16,
     AllocKind::OBJECT16,
     AllocKind::OBJECT16_BACKGROUND
 };
 
 void
 GCRuntime::updateAllCellPointers(MovingTracer* trc, Zone* zone)
 {
     size_t bgTaskCount = CellUpdateBackgroundTaskCount();
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -201,17 +201,17 @@ class ChainedIter
     }
 
     operator T() const { return get(); }
     T operator->() const { return get(); }
 };
 
 typedef HashMap<Value*, const char*, DefaultHasher<Value*>, SystemAllocPolicy> RootedValueMap;
 
-using AllocKinds = mozilla::EnumSet<AllocKind>;
+using AllocKinds = mozilla::EnumSet<AllocKind, uint64_t>;
 
 // A singly linked list of zones.
 class ZoneList
 {
     static Zone * const End;
 
     Zone* head;
     Zone* tail;
--- a/js/src/gc/ObjectKind-inl.h
+++ b/js/src/gc/ObjectKind-inl.h
@@ -119,25 +119,29 @@ GetGCKindSlots(AllocKind thingKind)
       case AllocKind::FUNCTION:
       case AllocKind::OBJECT0:
       case AllocKind::OBJECT0_BACKGROUND:
         return 0;
       case AllocKind::FUNCTION_EXTENDED:
       case AllocKind::OBJECT2:
       case AllocKind::OBJECT2_BACKGROUND:
         return 2;
+      case AllocKind::ARRAYBUFFER4:
       case AllocKind::OBJECT4:
       case AllocKind::OBJECT4_BACKGROUND:
         return 4;
+      case AllocKind::ARRAYBUFFER8:
       case AllocKind::OBJECT8:
       case AllocKind::OBJECT8_BACKGROUND:
         return 8;
+      case AllocKind::ARRAYBUFFER12:
       case AllocKind::OBJECT12:
       case AllocKind::OBJECT12_BACKGROUND:
         return 12;
+      case AllocKind::ARRAYBUFFER16:
       case AllocKind::OBJECT16:
       case AllocKind::OBJECT16_BACKGROUND:
         return 16;
       default:
         MOZ_CRASH("Bad object alloc kind");
     }
 }
 
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -1183,16 +1183,31 @@ ArrayBufferObject::flags() const
 }
 
 void
 ArrayBufferObject::setFlags(uint32_t flags)
 {
     setFixedSlot(FLAGS_SLOT, Int32Value(flags));
 }
 
+static inline AllocKind
+GetArrayBufferGCObjectKind(size_t numSlots)
+{
+    if (numSlots <= 4) {
+        return AllocKind::ARRAYBUFFER4;
+    }
+    if (numSlots <= 8) {
+        return AllocKind::ARRAYBUFFER8;
+    }
+    if (numSlots <= 12) {
+        return AllocKind::ARRAYBUFFER12;
+    }
+    return AllocKind::ARRAYBUFFER16;
+}
+
 ArrayBufferObject*
 ArrayBufferObject::create(JSContext* cx, uint32_t nbytes, BufferContents contents,
                           OwnsState ownsState /* = OwnsData */,
                           HandleObject proto /* = nullptr */,
                           NewObjectKind newKind /* = GenericObject */)
 {
     MOZ_ASSERT_IF(contents.kind() == MAPPED, contents);
 
@@ -1241,17 +1256,17 @@ ArrayBufferObject::create(JSContext* cx,
             contents = AllocateArrayBufferContents(cx, nbytes);
             if (!contents)
                 return nullptr;
             allocated = true;
         }
     }
 
     MOZ_ASSERT(!(class_.flags & JSCLASS_HAS_PRIVATE));
-    gc::AllocKind allocKind = GetGCObjectKind(nslots);
+    gc::AllocKind allocKind = GetArrayBufferGCObjectKind(nslots);
 
     AutoSetNewObjectMetadata metadata(cx);
     Rooted<ArrayBufferObject*> obj(cx,
         NewObjectWithClassProto<ArrayBufferObject>(cx, proto, allocKind, newKind));
     if (!obj) {
         if (allocated)
             js_free(contents.data());
         return nullptr;