Don't use JSFunction's allocation profile when getting the prototype can be effectful
https://bugs.webkit.org/show_bug.cgi?id=182942
<rdar://problem/37584764>

Reviewed by Mark Lam.

JSTests:

* stress/get-prototype-create-this-effectful.js: Added.

Source/JavaScriptCore:

Prior to this patch, the create_this implementation assumed that anything
that is a JSFunction can use the object allocation profile and go down the
fast path to allocate the |this| object. Implied by this approach is that
accessing the 'prototype' property of the incoming function is not an
effectful operation. This is inherent to the ObjectAllocationProfile
data structure: it caches the prototype field. However, getting the
'prototype' property might be an effectful operation, e.g, it could
be a getter. Many variants of functions in JS have the 'prototype' property
as non-configurable. However, some functions, like bound functions, do not
have the 'prototype' field with these attributes.

This patch adds the notion of 'canUseAllocationProfile' to JSFunction
and threads it through so that we only go down the fast path and use
the allocation profile when the prototype property is non-configurable.

* bytecompiler/NodesCodegen.cpp:
(JSC::ClassExprNode::emitBytecode):
* dfg/DFGOperations.cpp:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/JSFunction.cpp:
(JSC::JSFunction::prototypeForConstruction):
(JSC::JSFunction::allocateAndInitializeRareData):
(JSC::JSFunction::initializeRareData):
(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::canUseAllocationProfileNonInline):
* runtime/JSFunction.h:
(JSC::JSFunction::ensureRareDataAndAllocationProfile):
* runtime/JSFunctionInlines.h:
(JSC::JSFunction::canUseAllocationProfile):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@228725 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/runtime/JSFunctionInlines.h b/Source/JavaScriptCore/runtime/JSFunctionInlines.h
index a0adede..2278939 100644
--- a/Source/JavaScriptCore/runtime/JSFunctionInlines.h
+++ b/Source/JavaScriptCore/runtime/JSFunctionInlines.h
@@ -107,4 +107,26 @@
     return m_rareData ? m_rareData->hasReifiedName() : false;
 }
 
+inline bool JSFunction::canUseAllocationProfile()
+{
+    if (isHostFunction())
+        return false;
+
+    // If we don't have a prototype property, we're not guaranteed it's
+    // non-configurable. For example, user code can define the prototype
+    // as a getter. JS semantics require that the getter is called every
+    // time |construct| occurs with this function as new.target.
+    return jsExecutable()->hasPrototypeProperty();
+}
+
+inline FunctionRareData* JSFunction::ensureRareDataAndAllocationProfile(ExecState* exec, unsigned inlineCapacity)
+{
+    ASSERT(canUseAllocationProfile());
+    if (UNLIKELY(!m_rareData))
+        return allocateAndInitializeRareData(exec, inlineCapacity);
+    if (UNLIKELY(!m_rareData->isObjectAllocationProfileInitialized()))
+        return initializeRareData(exec, inlineCapacity);
+    return m_rareData.get();
+}
+
 } // namespace JSC