Title: [231345] trunk
Revision
231345
Author
sbar...@apple.com
Date
2018-05-03 21:33:53 -0700 (Thu, 03 May 2018)

Log Message

Don't prevent CreateThis being folded to NewObject when the structure is poly proto
https://bugs.webkit.org/show_bug.cgi?id=185177

Reviewed by Filip Pizlo.

JSTests:

* microbenchmarks/construct-poly-proto-object.js: Added.
(foo.A):
(foo):
* stress/allocation-sinking-new-object-with-poly-proto.js: Added.
(foo.A):
(foo):
(makePolyProto):
(bar):
(baz):

Source/_javascript_Core:

This patch teaches the DFG/FTL how to constant fold CreateThis with
a known poly proto Structure to NewObject. We do it by emitting a NewObject
followed by a PutByOffset for the prototype value.

We make it so that ObjectAllocationProfile holds the prototype value.
This is sound because JSFunction clears that profile when its 'prototype'
field changes.

This patch also renames underscoreProtoPrivateName to polyProtoName since
that name was nonsensical: it was only used for poly proto.

This is a 2x speedup on the get_callee_polymorphic microbenchmark. I had
regressed that benchmark when I first introduced poly proto.

* builtins/BuiltinNames.cpp:
* builtins/BuiltinNames.h:
(JSC::BuiltinNames::BuiltinNames):
(JSC::BuiltinNames::polyProtoName const):
(JSC::BuiltinNames::underscoreProtoPrivateName const): Deleted.
* bytecode/ObjectAllocationProfile.h:
(JSC::ObjectAllocationProfile::prototype):
(JSC::ObjectAllocationProfile::clear):
(JSC::ObjectAllocationProfile::visitAggregate):
* bytecode/ObjectAllocationProfileInlines.h:
(JSC::ObjectAllocationProfile::initializeProfile):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGOperations.cpp:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/FunctionRareData.h:
* runtime/Structure.cpp:
(JSC::Structure::create):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (231344 => 231345)


--- trunk/JSTests/ChangeLog	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/JSTests/ChangeLog	2018-05-04 04:33:53 UTC (rev 231345)
@@ -1,3 +1,20 @@
+2018-05-03  Saam Barati  <sbar...@apple.com>
+
+        Don't prevent CreateThis being folded to NewObject when the structure is poly proto
+        https://bugs.webkit.org/show_bug.cgi?id=185177
+
+        Reviewed by Filip Pizlo.
+
+        * microbenchmarks/construct-poly-proto-object.js: Added.
+        (foo.A):
+        (foo):
+        * stress/allocation-sinking-new-object-with-poly-proto.js: Added.
+        (foo.A):
+        (foo):
+        (makePolyProto):
+        (bar):
+        (baz):
+
 2018-05-03  Michael Saboff  <msab...@apple.com>
 
         OSR entry pruning of Program Bytecodes doesn't take into account try/catch

Added: trunk/JSTests/microbenchmarks/construct-poly-proto-object.js (0 => 231345)


--- trunk/JSTests/microbenchmarks/construct-poly-proto-object.js	                        (rev 0)
+++ trunk/JSTests/microbenchmarks/construct-poly-proto-object.js	2018-05-04 04:33:53 UTC (rev 231345)
@@ -0,0 +1,21 @@
+function foo() {
+    class A {
+        constructor() {
+            this.x = 25;
+            this.y = 30;
+        }
+    };
+    return A;
+}
+let A = foo();
+let B = foo();
+noInline(A);
+noInline(B);
+
+for (let i = 0; i < 400000; ++i) {
+    let b = !!(i % 2);
+    if (b)
+        new A;
+    else
+        new B;
+}

Added: trunk/JSTests/stress/allocation-sinking-new-object-with-poly-proto.js (0 => 231345)


--- trunk/JSTests/stress/allocation-sinking-new-object-with-poly-proto.js	                        (rev 0)
+++ trunk/JSTests/stress/allocation-sinking-new-object-with-poly-proto.js	2018-05-04 04:33:53 UTC (rev 231345)
@@ -0,0 +1,53 @@
+function foo() {
+    class A {
+        constructor() {
+        }
+    };
+    return A;
+}
+let A = foo();
+let B = foo();
+
+function makePolyProto(o) {
+    return o.x;
+}
+noInline(makePolyProto);
+
+for (let i = 0; i < 1000; ++i) {
+    makePolyProto(i % 2 ? new A : new B);
+}
+
+function bar(b) {
+    let o = new A;
+    if (b) {
+        if (isFinalTier())
+            OSRExit();
+        return o;
+    }
+}
+noInline(bar);
+
+function baz(b) {
+    let o = new A;
+    if (b)
+        return o;
+}
+noInline(baz);
+
+for (let i = 0; i < 100000; ++i) {
+    let b = i % 10 === 0;
+    let r = bar(b);
+    if (b) {
+        if (r.__proto__ !== A.prototype)
+            throw new Error("Bad!");
+    }
+}
+
+for (let i = 0; i < 100000; ++i) {
+    let b = i % 10 === 0;
+    let r = baz(b);
+    if (b) {
+        if (r.__proto__ !== A.prototype)
+            throw new Error("Bad!");
+    }
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (231344 => 231345)


--- trunk/Source/_javascript_Core/ChangeLog	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-05-04 04:33:53 UTC (rev 231345)
@@ -1,3 +1,48 @@
+2018-05-03  Saam Barati  <sbar...@apple.com>
+
+        Don't prevent CreateThis being folded to NewObject when the structure is poly proto
+        https://bugs.webkit.org/show_bug.cgi?id=185177
+
+        Reviewed by Filip Pizlo.
+
+        This patch teaches the DFG/FTL how to constant fold CreateThis with
+        a known poly proto Structure to NewObject. We do it by emitting a NewObject
+        followed by a PutByOffset for the prototype value.
+        
+        We make it so that ObjectAllocationProfile holds the prototype value.
+        This is sound because JSFunction clears that profile when its 'prototype'
+        field changes.
+        
+        This patch also renames underscoreProtoPrivateName to polyProtoName since
+        that name was nonsensical: it was only used for poly proto.
+        
+        This is a 2x speedup on the get_callee_polymorphic microbenchmark. I had
+        regressed that benchmark when I first introduced poly proto.
+
+        * builtins/BuiltinNames.cpp:
+        * builtins/BuiltinNames.h:
+        (JSC::BuiltinNames::BuiltinNames):
+        (JSC::BuiltinNames::polyProtoName const):
+        (JSC::BuiltinNames::underscoreProtoPrivateName const): Deleted.
+        * bytecode/ObjectAllocationProfile.h:
+        (JSC::ObjectAllocationProfile::prototype):
+        (JSC::ObjectAllocationProfile::clear):
+        (JSC::ObjectAllocationProfile::visitAggregate):
+        * bytecode/ObjectAllocationProfileInlines.h:
+        (JSC::ObjectAllocationProfile::initializeProfile):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGOperations.cpp:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/FunctionRareData.h:
+        * runtime/Structure.cpp:
+        (JSC::Structure::create):
+
 2018-05-03  Michael Saboff  <msab...@apple.com>
 
         OSR entry pruning of Program Bytecodes doesn't take into account try/catch

Modified: trunk/Source/_javascript_Core/builtins/BuiltinNames.cpp (231344 => 231345)


--- trunk/Source/_javascript_Core/builtins/BuiltinNames.cpp	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/builtins/BuiltinNames.cpp	2018-05-04 04:33:53 UTC (rev 231345)
@@ -44,7 +44,7 @@
 #undef INITIALIZE_BUILTIN_PRIVATE_NAMES
 
 SymbolImpl::StaticSymbolImpl dollarVMPrivateName { "PrivateSymbol.$vm", SymbolImpl::s_flagIsPrivate };
-SymbolImpl::StaticSymbolImpl underscoreProtoPrivateName { "PrivateSymbol.__proto__", SymbolImpl::s_flagIsPrivate };
+SymbolImpl::StaticSymbolImpl polyProtoPrivateName { "PrivateSymbol.PolyProto", SymbolImpl::s_flagIsPrivate };
 
 } // namespace Symbols
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/builtins/BuiltinNames.h (231344 => 231345)


--- trunk/Source/_javascript_Core/builtins/BuiltinNames.h	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/builtins/BuiltinNames.h	2018-05-04 04:33:53 UTC (rev 231345)
@@ -204,7 +204,7 @@
 #undef DECLARE_BUILTIN_PRIVATE_NAMES
 
 extern SymbolImpl::StaticSymbolImpl dollarVMPrivateName;
-extern SymbolImpl::StaticSymbolImpl underscoreProtoPrivateName;
+extern SymbolImpl::StaticSymbolImpl polyProtoPrivateName;
 }
 
 #define INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY(name) m_privateToPublicMap.add(m_##name##PrivateName.impl(), &m_##name);
@@ -229,7 +229,7 @@
         JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_BUILTIN_SYMBOLS)
         , m_dollarVMName(Identifier::fromString(vm, "$vm"))
         , m_dollarVMPrivateName(Identifier::fromUid(vm, &static_cast<SymbolImpl&>(Symbols::dollarVMPrivateName)))
-        , m_underscoreProtoPrivateName(Identifier::fromUid(vm, &static_cast<SymbolImpl&>(Symbols::underscoreProtoPrivateName)))
+        , m_polyProtoPrivateName(Identifier::fromUid(vm, &static_cast<SymbolImpl&>(Symbols::polyProtoPrivateName)))
     {
         JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY)
         JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY)
@@ -238,8 +238,6 @@
         JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_SYMBOL_PUBLIC_TO_PRIVATE_ENTRY)
         m_privateToPublicMap.add(m_dollarVMPrivateName.impl(), &m_dollarVMName);
         m_publicToPrivateMap.add(m_dollarVMName.impl(), &m_dollarVMPrivateName);
-        m_privateToPublicMap.add(m_underscoreProtoPrivateName.impl(), &commonIdentifiers->underscoreProto);
-        m_publicToPrivateMap.add(commonIdentifiers->underscoreProto.impl(), &m_underscoreProtoPrivateName);
     }
 
     const Identifier* lookUpPrivateName(const Identifier&) const;
@@ -252,7 +250,7 @@
     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOL_ACCESSOR)
     const JSC::Identifier& dollarVMPublicName() const { return m_dollarVMName; }
     const JSC::Identifier& dollarVMPrivateName() const { return m_dollarVMPrivateName; }
-    const JSC::Identifier& underscoreProtoPrivateName() const { return m_underscoreProtoPrivateName; }
+    const JSC::Identifier& polyProtoName() const { return m_polyProtoPrivateName; }
 
 private:
     Identifier m_emptyIdentifier;
@@ -261,7 +259,7 @@
     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOLS)
     const JSC::Identifier m_dollarVMName;
     const JSC::Identifier m_dollarVMPrivateName;
-    const JSC::Identifier m_underscoreProtoPrivateName;
+    const JSC::Identifier m_polyProtoPrivateName;
     typedef HashMap<RefPtr<UniquedStringImpl>, const Identifier*, IdentifierRepHash> BuiltinNamesMap;
     BuiltinNamesMap m_publicToPrivateMap;
     BuiltinNamesMap m_privateToPublicMap;

Modified: trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.h (231344 => 231345)


--- trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.h	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.h	2018-05-04 04:33:53 UTC (rev 231345)
@@ -58,12 +58,20 @@
         WTF::loadLoadFence();
         return structure;
     }
+    JSObject* prototype()
+    {
+        JSObject* prototype = m_prototype.get();
+        WTF::loadLoadFence();
+        return prototype;
+    }
     unsigned inlineCapacity() { return m_inlineCapacity; }
 
+
     void clear()
     {
         m_allocator = Allocator();
         m_structure.clear();
+        m_prototype.clear();
         m_inlineCapacity = 0;
         ASSERT(isNull());
     }
@@ -71,6 +79,7 @@
     void visitAggregate(SlotVisitor& visitor)
     {
         visitor.append(m_structure);
+        visitor.append(m_prototype);
     }
 
 private:
@@ -78,6 +87,7 @@
 
     Allocator m_allocator; // Precomputed to make things easier for generated code.
     WriteBarrier<Structure> m_structure;
+    WriteBarrier<JSObject> m_prototype;
     unsigned m_inlineCapacity;
 };
 

Modified: trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h (231344 => 231345)


--- trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h	2018-05-04 04:33:53 UTC (rev 231345)
@@ -35,11 +35,12 @@
 {
     ASSERT(!m_allocator);
     ASSERT(!m_structure);
+    ASSERT(!m_prototype);
     ASSERT(!m_inlineCapacity);
 
-    // FIXME: When going poly proto, we should make an allocator and teach
-    // create_this' fast path how to allocate a poly proto object.
-    // https://bugs.webkit.org/show_bug.cgi?id=177517
+    // FIXME: Teach create_this's fast path how to allocate poly
+    // proto objects: https://bugs.webkit.org/show_bug.cgi?id=177517
+
     bool isPolyProto = false;
     FunctionExecutable* executable = nullptr;
     if (constructor) {
@@ -55,6 +56,7 @@
             RELEASE_ASSERT(structure->typeInfo().type() == FinalObjectType);
             m_allocator = Allocator();
             m_structure.set(vm, owner, structure);
+            m_prototype.set(vm, owner, prototype);
             m_inlineCapacity = structure->inlineCapacity();
             return;
         }
@@ -132,10 +134,11 @@
         m_allocator = allocator;
     }
 
-    // Ensure that if another thread sees the structure, it will see it properly created
+    // Ensure that if another thread sees the structure and prototype, it will see it properly created.
     WTF::storeStoreFence();
 
     m_structure.set(vm, owner, structure);
+    m_prototype.set(vm, owner, prototype);
     m_inlineCapacity = inlineCapacity;
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (231344 => 231345)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-05-04 04:33:53 UTC (rev 231345)
@@ -2318,16 +2318,12 @@
             if (auto* function = jsDynamicCast<JSFunction*>(m_vm, base)) {
                 if (FunctionRareData* rareData = function->rareData()) {
                     if (Structure* structure = rareData->objectAllocationStructure()) {
-                        // FIXME: we should be able to allocate a poly proto object here:
-                        // https://bugs.webkit.org/show_bug.cgi?id=177517
-                        if (structure->hasMonoProto()) {
-                            m_graph.freeze(rareData);
-                            m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
-                            m_state.setFoundConstants(true);
-                            didFoldClobberWorld();
-                            forNode(node).set(m_graph, structure);
-                            break;
-                        }
+                        m_graph.freeze(rareData);
+                        m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
+                        m_state.setFoundConstants(true);
+                        didFoldClobberWorld();
+                        forNode(node).set(m_graph, structure);
+                        break;
                     }
                 }
             }

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (231344 => 231345)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2018-05-04 04:33:53 UTC (rev 231345)
@@ -31,6 +31,7 @@
 #include "ArithProfile.h"
 #include "ArrayConstructor.h"
 #include "BasicBlockLocation.h"
+#include "BuiltinNames.h"
 #include "BytecodeStructs.h"
 #include "CallLinkStatus.h"
 #include "CodeBlock.h"
@@ -4485,15 +4486,29 @@
             bool alreadyEmitted = false;
             if (function) {
                 if (FunctionRareData* rareData = function->rareData()) {
-                    if (Structure* structure = rareData->objectAllocationStructure()) {
-                        // FIXME: we should be able to allocate a poly proto object here:
-                        // https://bugs.webkit.org/show_bug.cgi?id=177517
-                        if (structure->hasMonoProto()) {
+                    if (rareData->allocationProfileWatchpointSet().isStillValid()) {
+                        Structure* structure = rareData->objectAllocationStructure();
+                        JSObject* prototype = rareData->objectAllocationPrototype();
+                        if (structure
+                            && (structure->hasMonoProto() || prototype)
+                            && rareData->allocationProfileWatchpointSet().isStillValid()) {
+
                             m_graph.freeze(rareData);
                             m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
                             // The callee is still live up to this point.
                             addToGraph(Phantom, callee);
-                            set(VirtualRegister(bytecode.dst()), addToGraph(NewObject, OpInfo(m_graph.registerStructure(structure))));
+                            Node* object = addToGraph(NewObject, OpInfo(m_graph.registerStructure(structure)));
+                            if (structure->hasPolyProto()) {
+                                StorageAccessData* data = ""
+                                data->offset = knownPolyProtoOffset;
+                                data->identifierNumber = m_graph.identifiers().ensure(m_graph.m_vm.propertyNames->builtinNames().polyProtoName().impl());
+                                InferredType::Descriptor inferredType = InferredType::Top;
+                                data->inferredType = inferredType;
+                                m_graph.registerInferredType(inferredType);
+                                ASSERT(isInlineOffset(knownPolyProtoOffset));
+                                addToGraph(PutByOffset, OpInfo(data), object, object, weakJSConstant(prototype));
+                            }
+                            set(VirtualRegister(bytecode.dst()), object);
                             alreadyEmitted = true;
                         }
                     }

Modified: trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (231344 => 231345)


--- trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp	2018-05-04 04:33:53 UTC (rev 231345)
@@ -28,6 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "BuiltinNames.h"
 #include "DFGAbstractInterpreterInlines.h"
 #include "DFGArgumentsUtilities.h"
 #include "DFGBasicBlockInlines.h"
@@ -643,15 +644,37 @@
                 if (JSValue base = m_state.forNode(node->child1()).m_value) {
                     if (auto* function = jsDynamicCast<JSFunction*>(m_graph.m_vm, base)) {
                         if (FunctionRareData* rareData = function->rareData()) {
-                            if (Structure* structure = rareData->objectAllocationStructure()) {
-                                // FIXME: we should be able to allocate a poly proto object here:
-                                // https://bugs.webkit.org/show_bug.cgi?id=177517
-                                if (structure->hasMonoProto()) {
+                            if (rareData->allocationProfileWatchpointSet().isStillValid()) {
+                                Structure* structure = rareData->objectAllocationStructure();
+                                JSObject* prototype = rareData->objectAllocationPrototype();
+                                if (structure
+                                    && (structure->hasMonoProto() || prototype)
+                                    && rareData->allocationProfileWatchpointSet().isStillValid()) {
+
                                     m_graph.freeze(rareData);
                                     m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
                                     node->convertToNewObject(m_graph.registerStructure(structure));
+
+                                    if (structure->hasPolyProto()) {
+                                        StorageAccessData* data = ""
+                                        data->offset = knownPolyProtoOffset;
+                                        data->identifierNumber = m_graph.identifiers().ensure(m_graph.m_vm.propertyNames->builtinNames().polyProtoName().impl());
+                                        InferredType::Descriptor inferredType = InferredType::Top;
+                                        data->inferredType = inferredType;
+                                        m_graph.registerInferredType(inferredType);
+
+                                        NodeOrigin origin = node->origin.withInvalidExit();
+                                        Node* prototypeNode = m_insertionSet.insertConstant(
+                                            indexInBlock + 1, origin, m_graph.freeze(prototype));
+
+                                        ASSERT(isInlineOffset(knownPolyProtoOffset));
+                                        m_insertionSet.insertNode(
+                                            indexInBlock + 1, SpecNone, PutByOffset, origin, OpInfo(data),
+                                            Edge(node, KnownCellUse), Edge(node, KnownCellUse), Edge(prototypeNode, UntypedUse));
+                                    }
                                     changed = true;
                                     break;
+
                                 }
                             }
                         }

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (231344 => 231345)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2018-05-04 04:33:53 UTC (rev 231345)
@@ -250,10 +250,12 @@
     if (constructor->type() == JSFunctionType && jsCast<JSFunction*>(constructor)->canUseAllocationProfile()) {
         auto rareData = jsCast<JSFunction*>(constructor)->ensureRareDataAndAllocationProfile(exec, inlineCapacity);
         RETURN_IF_EXCEPTION(scope, nullptr);
-        Structure* structure = rareData->objectAllocationProfile()->structure();
+        ObjectAllocationProfile* allocationProfile = rareData->objectAllocationProfile();
+        Structure* structure = allocationProfile->structure();
         JSObject* result = constructEmptyObject(exec, structure);
         if (structure->hasPolyProto()) {
-            JSObject* prototype = jsCast<JSFunction*>(constructor)->prototypeForConstruction(vm, exec);
+            JSObject* prototype = allocationProfile->prototype();
+            ASSERT(prototype == jsCast<JSFunction*>(constructor)->prototypeForConstruction(vm, exec));
             result->putDirect(vm, knownPolyProtoOffset, prototype);
             prototype->didBecomePrototype();
             ASSERT_WITH_MESSAGE(!hasIndexedProperties(result->indexingType()), "We rely on JSFinalObject not starting out with an indexing type otherwise we would potentially need to convert to slow put storage");

Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (231344 => 231345)


--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2018-05-04 04:33:53 UTC (rev 231345)
@@ -224,10 +224,12 @@
             cachedCallee.setWithoutWriteBarrier(JSCell::seenMultipleCalleeObjects());
 
         size_t inlineCapacity = bytecode.inlineCapacity();
-        Structure* structure = constructor->ensureRareDataAndAllocationProfile(exec, inlineCapacity)->objectAllocationProfile()->structure();
+        ObjectAllocationProfile* allocationProfile = constructor->ensureRareDataAndAllocationProfile(exec, inlineCapacity)->objectAllocationProfile();
+        Structure* structure = allocationProfile->structure();
         result = constructEmptyObject(exec, structure);
         if (structure->hasPolyProto()) {
-            JSObject* prototype = constructor->prototypeForConstruction(vm, exec);
+            JSObject* prototype = allocationProfile->prototype();
+            ASSERT(prototype == constructor->prototypeForConstruction(vm, exec));
             result->putDirect(vm, knownPolyProtoOffset, prototype);
             prototype->didBecomePrototype();
             ASSERT_WITH_MESSAGE(!hasIndexedProperties(result->indexingType()), "We rely on JSFinalObject not starting out with an indexing type otherwise we would potentially need to convert to slow put storage");

Modified: trunk/Source/_javascript_Core/runtime/FunctionRareData.h (231344 => 231345)


--- trunk/Source/_javascript_Core/runtime/FunctionRareData.h	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/runtime/FunctionRareData.h	2018-05-04 04:33:53 UTC (rev 231345)
@@ -71,6 +71,7 @@
     }
 
     Structure* objectAllocationStructure() { return m_objectAllocationProfile.structure(); }
+    JSObject* objectAllocationPrototype() { return m_objectAllocationProfile.prototype(); }
 
     InlineWatchpointSet& allocationProfileWatchpointSet()
     {

Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (231344 => 231345)


--- trunk/Source/_javascript_Core/runtime/Structure.cpp	2018-05-04 01:50:47 UTC (rev 231344)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp	2018-05-04 04:33:53 UTC (rev 231345)
@@ -306,7 +306,7 @@
 
     unsigned oldOutOfLineCapacity = result->outOfLineCapacity();
     result->addPropertyWithoutTransition(
-        vm, vm.propertyNames->builtinNames().underscoreProtoPrivateName(), static_cast<unsigned>(PropertyAttribute::DontEnum),
+        vm, vm.propertyNames->builtinNames().polyProtoName(), static_cast<unsigned>(PropertyAttribute::DontEnum),
         [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newLastOffset) {
             RELEASE_ASSERT(Structure::outOfLineCapacity(newLastOffset) == oldOutOfLineCapacity);
             RELEASE_ASSERT(offset == knownPolyProtoOffset);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to