[JSC] Strict, Sloppy and Arrow functions should have different classInfo
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 22 Jun 2019 07:48:08 +0000 (07:48 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 22 Jun 2019 07:48:08 +0000 (07:48 +0000)
commit4459d3d43286aa1cbf89252647a8e9a080930794
treefe7f388a046722d3353efb0f28f7a857b34491dd
parent870b946a0995f91ba15964fb2941beb21d801a5e
[JSC] Strict, Sloppy and Arrow functions should have different classInfo
https://bugs.webkit.org/show_bug.cgi?id=197631

Reviewed by Saam Barati.

JSTests:

* stress/has-own-property-arguments.js: Added.
(shouldBe):
(A):

Source/JavaScriptCore:

If a constructor inherits a builtin class, it creates a Structure which is subclassing the builtin class.
This is done by using InternalFunction::createSubclassStructure. But to accelerate the common cases, we
cache the created structure in InternalFunctionAllocationProfile. Whether the cache is valid is checked
by comparing classInfo of the cached structure and the given base structure. This implicitly assume that
each builtin class's InternalFunction creates an instance based on one structure.

However, Function constructor is an exception: Function constructor creates an instance which has different
structures based on a parameter. If a strict code is given (e.g. "'use strict'"), it creates a function
instance with strict function structure.

As a result, InternalFunctionAllocationProfile incorrectly caches the structure. Consider the following code.

    class A extends Function { };
    let a = new A("'use strict'");
    let b = new A("");

While `a` and `b` should have different structures, `A` caches the structure for `a`, and reuse it even the given
code is not a strict code. This is problematic: We are separating structures of strict, sloppy, and arrow functions
because they have different properties. However, in the above case, a and b have the same structure while they have
different properties. So it causes incorrect structure-based caching in JSC. One of the example is HasOwnPropertyCache.

In this patch, we introduce JSStrictFunction, JSSloppyFunction, and JSArrowFunction classes and classInfos. This design
works well and already partially accepted for JSGeneratorFunction, JSAsyncGeneratorFunction, and JSAsyncFunction. Each
structure now has a different classInfo so that InternalFunctionAllocationProfile correctly caches and invalidates the
cached one based on the classInfo. Since we already have different structures for these instances, and DFG and FTL
optimizations are based on JSFunctionType (not classInfo), introducing these three classInfo do not break the optimization.

Note that structures on ArrayConstructor does not cause the same problem. It only uses Undecided indexing typed array
structure in InternalFunctionAllocationProfile, and once haveABadTime happens, it clears InternalFunctionAllocationProfile.

* runtime/JSAsyncFunction.h: This subspaceFor is not necessary since it is defined in JSFunction. And we already ensure that
sizeof(JSAsyncFunction) == sizeof(JSFunction).
* runtime/JSAsyncGeneratorFunction.cpp:
* runtime/JSAsyncGeneratorFunction.h: Ditto.
* runtime/JSFunction.cpp:
* runtime/JSFunction.h:
* runtime/JSGeneratorFunction.h: Ditto.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246709 268f45cc-cd09-0410-ab3c-d52691b4dbfc
JSTests/ChangeLog
JSTests/stress/has-own-property-arguments.js [new file with mode: 0644]
JSTests/stress/inline-cache-arguments.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSAsyncFunction.h
Source/JavaScriptCore/runtime/JSAsyncGeneratorFunction.cpp
Source/JavaScriptCore/runtime/JSAsyncGeneratorFunction.h
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSFunction.h
Source/JavaScriptCore/runtime/JSGeneratorFunction.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp