flattenDictionaryStruture needs to zero inline storage.
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jun 2018 18:44:02 +0000 (18:44 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jun 2018 18:44:02 +0000 (18:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186869

Reviewed by Saam Barati.

JSTests:

* stress/flatten-object-zero-unused-inline-properties.js: Added.

Source/JavaScriptCore:

This patch also adds the assetion that unused property storage is
zero or JSValue() to putDirectInternal. Additionally, functions
have been added to $vm that flatten dictionary objects and return
the inline capacity of an object.

* runtime/JSObjectInlines.h:
(JSC::JSObject::putDirectInternal):
* runtime/Structure.cpp:
(JSC::Structure::flattenDictionaryStructure):
* tools/JSDollarVM.cpp:
(JSC::functionInlineCapacity):
(JSC::functionFlattenDictionaryObject):
(JSC::JSDollarVM::finishCreation):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233048 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/stress/flatten-object-zero-unused-inline-properties.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSObjectInlines.h
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/tools/JSDollarVM.cpp

index b83e27e..be4eb3c 100644 (file)
@@ -1,3 +1,12 @@
+2018-06-20  Keith Miller  <keith_miller@apple.com>
+
+        flattenDictionaryStruture needs to zero inline storage.
+        https://bugs.webkit.org/show_bug.cgi?id=186869
+
+        Reviewed by Saam Barati.
+
+        * stress/flatten-object-zero-unused-inline-properties.js: Added.
+
 2018-06-19  Saam Barati  <sbarati@apple.com>
 
         DirectArguments::create needs to initialize to undefined instead of the empty value
diff --git a/JSTests/stress/flatten-object-zero-unused-inline-properties.js b/JSTests/stress/flatten-object-zero-unused-inline-properties.js
new file mode 100644 (file)
index 0000000..6fe5a14
--- /dev/null
@@ -0,0 +1,7 @@
+let o = { foo: 1, bar: 2, baz: 3 };
+if ($vm.inlineCapacity(o) <= 3)
+    throw new Error("There should be inline capacity");
+
+delete o.foo;
+$vm.flattenDictionaryObject(o);
+o.foo = 1;
index 8838036..206d4b5 100644 (file)
@@ -1,3 +1,24 @@
+2018-06-20  Keith Miller  <keith_miller@apple.com>
+
+        flattenDictionaryStruture needs to zero inline storage.
+        https://bugs.webkit.org/show_bug.cgi?id=186869
+
+        Reviewed by Saam Barati.
+
+        This patch also adds the assetion that unused property storage is
+        zero or JSValue() to putDirectInternal. Additionally, functions
+        have been added to $vm that flatten dictionary objects and return
+        the inline capacity of an object.
+
+        * runtime/JSObjectInlines.h:
+        (JSC::JSObject::putDirectInternal):
+        * runtime/Structure.cpp:
+        (JSC::Structure::flattenDictionaryStructure):
+        * tools/JSDollarVM.cpp:
+        (JSC::functionInlineCapacity):
+        (JSC::functionFlattenDictionaryObject):
+        (JSC::JSDollarVM::finishCreation):
+
 2018-06-21  Mark Lam  <mark.lam@apple.com>
 
         Use IsoCellSets to track Executables with clearable code.
index a24a329..5e93e26 100644 (file)
@@ -381,6 +381,10 @@ ALWAYS_INLINE bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName
         Butterfly* newButterfly = allocateMoreOutOfLineStorage(vm, oldCapacity, newCapacity);
         nukeStructureAndSetButterfly(vm, structureID, newButterfly);
     }
+
+    // This assertion verifies that the concurrent GC won't read garbage if the concurrentGC
+    // is running at the same time we put without transitioning.
+    ASSERT(!getDirect(offset) || !JSValue::encode(getDirect(offset)));
     putDirect(vm, offset, value);
     setStructure(vm, newStructure);
     slot.setNewProperty(this, offset);
index 8e0219c..30eeee9 100644 (file)
@@ -782,6 +782,11 @@ Structure* Structure::flattenDictionaryStructure(VM& vm, JSObject* object)
 
         // We need to zero our unused property space; otherwise the GC might see a
         // stale pointer when we add properties in the future.
+        memset(
+            object->inlineStorageUnsafe() + inlineSize(),
+            0,
+            (inlineCapacity() - inlineSize()) * sizeof(EncodedJSValue));
+
         Butterfly* butterfly = object->butterfly();
         memset(
             butterfly->base(butterfly->indexingHeader()->preCapacity(this), beforeOutOfLineCapacity),
index 96204c6..17c4654 100644 (file)
@@ -1378,6 +1378,15 @@ static EncodedJSValue JSC_HOST_CALL functionIndexingMode(ExecState* exec)
     return JSValue::encode(jsString(exec, stream.toString()));
 }
 
+static EncodedJSValue JSC_HOST_CALL functionInlineCapacity(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    if (auto* object = jsDynamicCast<JSObject*>(vm, exec->argument(0)))
+        return JSValue::encode(jsNumber(object->structure(vm)->inlineCapacity()));
+
+    return encodedJSUndefined();
+}
+
 // Gets the dataLog dump of a given JS value as a string.
 // Usage: print("value = " + $vm.value(jsValue))
 static EncodedJSValue JSC_HOST_CALL functionValue(ExecState* exec)
@@ -1647,6 +1656,15 @@ static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)
     return JSValue::encode(JSONParse(exec, jsonString));
 }
 
+static EncodedJSValue JSC_HOST_CALL functionFlattenDictionaryObject(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    JSValue value = exec->argument(0);
+    RELEASE_ASSERT(value.isObject() && value.getObject()->structure()->isDictionary());
+    value.getObject()->flattenDictionaryObject(vm);
+    return encodedJSUndefined();
+}
+
 static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState* exec)
 {
     VM& vm = exec->vm();
@@ -1824,6 +1842,7 @@ void JSDollarVM::finishCreation(VM& vm)
     addFunction(vm, "printStack", functionPrintStack, 0);
 
     addFunction(vm, "indexingMode", functionIndexingMode, 1);
+    addFunction(vm, "inlineCapacity", functionInlineCapacity, 1);
     addFunction(vm, "value", functionValue, 1);
     addFunction(vm, "getpid", functionGetPID, 0);
 
@@ -1855,6 +1874,8 @@ void JSDollarVM::finishCreation(VM& vm)
     addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
     addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
 
+    addFunction(vm, "flattenDictionaryObject", functionFlattenDictionaryObject, 1);
+
     addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
     addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
     addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);