Skip to content
Permalink
Browse files
Move std::function from JSFunction into NativeStdFunctionCell to corr…
…ectly destroy the heap allocated std::function

https://bugs.webkit.org/show_bug.cgi?id=148262

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

std::function is heap allocated value. So if this is held in the JSCell, the cell should be destructible.
Before this patch, it is held in the JSStdFunction. JSStdFunction is the derived class from the JSFunction,
and they are not destructible. So it leaked the memory.

This patch extracts std::function field from the JSStdFunction to the NativeStdFunctionCell. NativeStdFunctionCell
is responsible for destructing the held std::function.
Instead of moving std::function to the ExecutableBase, we move it to the newly created NativeStdFunctionCell cell.
The reason is the following.

- Each NativeExecutable (in 64_32 JIT environment) has the trampolines to call given host functions.
  And the address of the host function is directly embedded on the JIT-compiled trampoline code.
- To suppress the overuse of the executable memory (which is used to generate the trampoline), NativeExecutable
  is cached. The host function address is used as the key to look up the cached executable from the table.
- In all the JSStdFunction, we use the same host function that immediately calls the each std::function.
- As a result, without any change, all the JSStdFunction hit the same cached NativeExecutable even if the held
  std::function is different.
- To solve it, if we put the std::function in the NativeExecutable, we need to add this std::function
  identity (like address) to the cache key, because the address of the stub host function (that calls the
  std::function) is the same in the all JSStdFunction.
- But since the std::function will be allocated in the heap, this address is always different. So caching has
  no effect.
- If we do not cache the NativeExecutable that holds the std::function, each time when creating the JSStdFunction,
  we need to regenerate the completely same trampolines (since it just calls the same host function stub that
  calls the std::function).

And this patch drops JSArrowFunction::destroy because (1) JSArrowFunction is not destructible and (2) it no longer
holds any fields that require destructions.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* jsc.cpp:
(runWithScripts):
* runtime/JSArrowFunction.cpp:
(JSC::JSArrowFunction::destroy): Deleted.
* runtime/JSArrowFunction.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::lookUpOrCreateNativeExecutable):
(JSC::JSFunction::create):
(JSC::getNativeExecutable): Deleted.
(JSC::JSStdFunction::JSStdFunction): Deleted.
(JSC::runStdFunction): Deleted.
* runtime/JSFunction.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::nativeStdFunctionStructure):
* runtime/JSNativeStdFunction.cpp: Added.
(JSC::JSNativeStdFunction::JSNativeStdFunction):
(JSC::JSNativeStdFunction::visitChildren):
(JSC::JSNativeStdFunction::finishCreation):
(JSC::runStdFunction):
(JSC::JSNativeStdFunction::create):
* runtime/JSNativeStdFunction.h: Copied from Source/JavaScriptCore/runtime/JSArrowFunction.h.
(JSC::JSNativeStdFunction::createStructure):
(JSC::JSNativeStdFunction::nativeStdFunctionCell):
* runtime/NativeStdFunctionCell.cpp: Added.
(JSC::NativeStdFunctionCell::create):
(JSC::NativeStdFunctionCell::NativeStdFunctionCell):
(JSC::NativeStdFunctionCell::destroy):
* runtime/NativeStdFunctionCell.h: Added.
(JSC::NativeStdFunctionCell::createStructure):
(JSC::NativeStdFunctionCell::function):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

Source/WebCore:

No behavior change.

Change JSFunction::create to JSNativeStdFunction::create to explicitly create the JSNativeStdFunction with the C++ lambda.

* ForwardingHeaders/runtime/JSNativeStdFunction.h: Added.
* bindings/js/ReadableJSStream.cpp:
(WebCore::createStartResultFulfilledFunction):
(WebCore::createPullResultFulfilledFunction):
(WebCore::createCancelResultFulfilledFunction):
(WebCore::createCancelResultRejectedFunction):
(WebCore::ReadableJSStream::ReadableJSStream):


Canonical link: https://commits.webkit.org/166702@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189124 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Constellation committed Aug 28, 2015
1 parent a6610da commit a961702751484f6de7c6f7019698133a56cc56a0
Showing 21 changed files with 418 additions and 43 deletions.
@@ -537,6 +537,7 @@ set(JavaScriptCore_RUNTIME_SOURCES
runtime/JSMap.cpp
runtime/JSMapIterator.cpp
runtime/JSModuleRecord.cpp
runtime/JSNativeStdFunction.cpp
runtime/JSNotAnObject.cpp
runtime/JSONObject.cpp
runtime/JSObject.cpp
@@ -574,6 +575,7 @@ set(JavaScriptCore_RUNTIME_SOURCES
runtime/ModuleLoaderObject.cpp
runtime/NativeErrorConstructor.cpp
runtime/NativeErrorPrototype.cpp
runtime/NativeStdFunctionCell.cpp
runtime/NullGetterFunction.cpp
runtime/NullSetterFunction.cpp
runtime/NumberConstructor.cpp
@@ -1,3 +1,79 @@
2015-08-28 Yusuke Suzuki <utatane.tea@gmail.com>

Move std::function from JSFunction into NativeStdFunctionCell to correctly destroy the heap allocated std::function
https://bugs.webkit.org/show_bug.cgi?id=148262

Reviewed by Filip Pizlo.

std::function is heap allocated value. So if this is held in the JSCell, the cell should be destructible.
Before this patch, it is held in the JSStdFunction. JSStdFunction is the derived class from the JSFunction,
and they are not destructible. So it leaked the memory.

This patch extracts std::function field from the JSStdFunction to the NativeStdFunctionCell. NativeStdFunctionCell
is responsible for destructing the held std::function.
Instead of moving std::function to the ExecutableBase, we move it to the newly created NativeStdFunctionCell cell.
The reason is the following.

- Each NativeExecutable (in 64_32 JIT environment) has the trampolines to call given host functions.
And the address of the host function is directly embedded on the JIT-compiled trampoline code.
- To suppress the overuse of the executable memory (which is used to generate the trampoline), NativeExecutable
is cached. The host function address is used as the key to look up the cached executable from the table.
- In all the JSStdFunction, we use the same host function that immediately calls the each std::function.
- As a result, without any change, all the JSStdFunction hit the same cached NativeExecutable even if the held
std::function is different.
- To solve it, if we put the std::function in the NativeExecutable, we need to add this std::function
identity (like address) to the cache key, because the address of the stub host function (that calls the
std::function) is the same in the all JSStdFunction.
- But since the std::function will be allocated in the heap, this address is always different. So caching has
no effect.
- If we do not cache the NativeExecutable that holds the std::function, each time when creating the JSStdFunction,
we need to regenerate the completely same trampolines (since it just calls the same host function stub that
calls the std::function).

And this patch drops JSArrowFunction::destroy because (1) JSArrowFunction is not destructible and (2) it no longer
holds any fields that require destructions.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* jsc.cpp:
(runWithScripts):
* runtime/JSArrowFunction.cpp:
(JSC::JSArrowFunction::destroy): Deleted.
* runtime/JSArrowFunction.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::lookUpOrCreateNativeExecutable):
(JSC::JSFunction::create):
(JSC::getNativeExecutable): Deleted.
(JSC::JSStdFunction::JSStdFunction): Deleted.
(JSC::runStdFunction): Deleted.
* runtime/JSFunction.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::nativeStdFunctionStructure):
* runtime/JSNativeStdFunction.cpp: Added.
(JSC::JSNativeStdFunction::JSNativeStdFunction):
(JSC::JSNativeStdFunction::visitChildren):
(JSC::JSNativeStdFunction::finishCreation):
(JSC::runStdFunction):
(JSC::JSNativeStdFunction::create):
* runtime/JSNativeStdFunction.h: Copied from Source/JavaScriptCore/runtime/JSArrowFunction.h.
(JSC::JSNativeStdFunction::createStructure):
(JSC::JSNativeStdFunction::nativeStdFunctionCell):
* runtime/NativeStdFunctionCell.cpp: Added.
(JSC::NativeStdFunctionCell::create):
(JSC::NativeStdFunctionCell::NativeStdFunctionCell):
(JSC::NativeStdFunctionCell::destroy):
* runtime/NativeStdFunctionCell.h: Added.
(JSC::NativeStdFunctionCell::createStructure):
(JSC::NativeStdFunctionCell::function):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

2015-08-28 Sukolsak Sakshuwong <sukolsak@gmail.com>

Create WebAssembly functions
@@ -786,6 +786,7 @@
<ClCompile Include="..\runtime\JSMap.cpp" />
<ClCompile Include="..\runtime\JSMapIterator.cpp" />
<ClCompile Include="..\runtime\JSModuleRecord.cpp" />
<ClCompile Include="..\runtime\JSNativeStdFunction.cpp" />
<ClCompile Include="..\runtime\JSNotAnObject.cpp" />
<ClCompile Include="..\runtime\JSONObject.cpp" />
<ClCompile Include="..\runtime\JSObject.cpp" />
@@ -824,6 +825,7 @@
<ClCompile Include="..\runtime\ModuleLoaderObject.cpp" />
<ClCompile Include="..\runtime\NativeErrorConstructor.cpp" />
<ClCompile Include="..\runtime\NativeErrorPrototype.cpp" />
<ClCompile Include="..\runtime\NativeStdFunctionCell.cpp" />
<ClCompile Include="..\runtime\NullGetterFunction.cpp" />
<ClCompile Include="..\runtime\NullSetterFunction.cpp" />
<ClCompile Include="..\runtime\NumberConstructor.cpp" />
@@ -1638,6 +1640,7 @@
<ClInclude Include="..\runtime\JSMap.h" />
<ClInclude Include="..\runtime\JSMapIterator.h" />
<ClInclude Include="..\runtime\JSModuleRecord.h" />
<ClInclude Include="..\runtime\JSNativeStdFunction.h" />
<ClInclude Include="..\runtime\JSNotAnObject.h" />
<ClInclude Include="..\runtime\JSONObject.h" />
<ClInclude Include="..\runtime\JSObject.h" />
@@ -1687,6 +1690,7 @@
<ClInclude Include="..\runtime\Microtask.h" />
<ClInclude Include="..\runtime\NativeErrorConstructor.h" />
<ClInclude Include="..\runtime\NativeErrorPrototype.h" />
<ClInclude Include="..\runtime\NativeStdFunctionCell.h" />
<ClInclude Include="..\runtime\NullGetterFunction.h" />
<ClInclude Include="..\runtime\NullSetterFunction.h" />
<ClInclude Include="..\runtime\NumberConstructor.h" />
@@ -726,6 +726,9 @@
<ClCompile Include="..\runtime\JSModuleRecord.cpp">
<Filter>runtime</Filter>
</ClCompile>
<ClCompile Include="..\runtime\JSNativeStdFunction.cpp">
<Filter>runtime</Filter>
</ClCompile>
<ClCompile Include="..\runtime\JSNotAnObject.cpp">
<Filter>runtime</Filter>
</ClCompile>
@@ -810,6 +813,9 @@
<ClCompile Include="..\runtime\NativeErrorPrototype.cpp">
<Filter>runtime</Filter>
</ClCompile>
<ClCompile Include="..\runtime\NativeStdFunctionCell.cpp">
<Filter>runtime</Filter>
</ClCompile>
<ClCompile Include="..\runtime\NullGetterFunction.cpp">
<Filter>runtime</Filter>
</ClCompile>
@@ -2934,6 +2940,9 @@
<ClInclude Include="..\runtime\NativeErrorPrototype.h">
<Filter>runtime</Filter>
</ClInclude>
<ClInclude Include="..\runtime\NativeStdFunctionCell.h">
<Filter>runtime</Filter>
</ClInclude>
<ClInclude Include="..\runtime\NullGetterFunction.h">
<Filter>runtime</Filter>
</ClInclude>
@@ -3493,6 +3502,9 @@
<ClInclude Include="..\runtime\JSModuleRecord.h">
<Filter>runtime</Filter>
</ClInclude>
<ClInclude Include="..\runtime\JSNativeStdFunction.h">
<Filter>runtime</Filter>
</ClInclude>
<ClInclude Include="..\runtime\JSSet.h">
<Filter>runtime</Filter>
</ClInclude>
@@ -1703,6 +1703,10 @@
E33637A51B63220200EE0840 /* ReflectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33637A31B63220200EE0840 /* ReflectObject.cpp */; };
E33637A61B63220200EE0840 /* ReflectObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E33637A41B63220200EE0840 /* ReflectObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
E33B3E261B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */; };
E33E8D1C1B9013C300346B52 /* JSNativeStdFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33E8D1A1B9013C300346B52 /* JSNativeStdFunction.cpp */; };
E33E8D1D1B9013C300346B52 /* JSNativeStdFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = E33E8D1B1B9013C300346B52 /* JSNativeStdFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
E33E8D201B9013DE00346B52 /* NativeStdFunctionCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33E8D1E1B9013DE00346B52 /* NativeStdFunctionCell.cpp */; };
E33E8D211B9013DE00346B52 /* NativeStdFunctionCell.h in Headers */ = {isa = PBXBuildFile; fileRef = E33E8D1F1B9013DE00346B52 /* NativeStdFunctionCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
E33F50741B8421C000413856 /* JSInternalPromisePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33F50721B8421C000413856 /* JSInternalPromisePrototype.cpp */; };
E33F50751B8421C000413856 /* JSInternalPromisePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F50731B8421C000413856 /* JSInternalPromisePrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
E33F50781B84225700413856 /* JSInternalPromiseConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33F50761B84225700413856 /* JSInternalPromiseConstructor.cpp */; };
@@ -3556,6 +3560,10 @@
E33637A31B63220200EE0840 /* ReflectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReflectObject.cpp; sourceTree = "<group>"; };
E33637A41B63220200EE0840 /* ReflectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.h; sourceTree = "<group>"; };
E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInstrumentationObject.lut.h; sourceTree = "<group>"; };
E33E8D1A1B9013C300346B52 /* JSNativeStdFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNativeStdFunction.cpp; sourceTree = "<group>"; };
E33E8D1B1B9013C300346B52 /* JSNativeStdFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNativeStdFunction.h; sourceTree = "<group>"; };
E33E8D1E1B9013DE00346B52 /* NativeStdFunctionCell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NativeStdFunctionCell.cpp; sourceTree = "<group>"; };
E33E8D1F1B9013DE00346B52 /* NativeStdFunctionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeStdFunctionCell.h; sourceTree = "<group>"; };
E33F50721B8421C000413856 /* JSInternalPromisePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInternalPromisePrototype.cpp; sourceTree = "<group>"; };
E33F50731B8421C000413856 /* JSInternalPromisePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternalPromisePrototype.h; sourceTree = "<group>"; };
E33F50761B84225700413856 /* JSInternalPromiseConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInternalPromiseConstructor.cpp; sourceTree = "<group>"; };
@@ -4767,6 +4775,8 @@
A74DEF90182D991400522C22 /* JSMapIterator.h */,
E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */,
E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */,
E33E8D1A1B9013C300346B52 /* JSNativeStdFunction.cpp */,
E33E8D1B1B9013C300346B52 /* JSNativeStdFunction.h */,
A72700780DAC605600E548D7 /* JSNotAnObject.cpp */,
A72700770DAC605600E548D7 /* JSNotAnObject.h */,
BC22A3980E16E14800AF21C8 /* JSObject.cpp */,
@@ -4852,6 +4862,8 @@
BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */,
BC02E90A0E1839DB000F9297 /* NativeErrorPrototype.cpp */,
BC02E90B0E1839DB000F9297 /* NativeErrorPrototype.h */,
E33E8D1E1B9013DE00346B52 /* NativeStdFunctionCell.cpp */,
E33E8D1F1B9013DE00346B52 /* NativeStdFunctionCell.h */,
6546F51F1A32A59C006F07D5 /* NullGetterFunction.cpp */,
6546F5201A32A59C006F07D5 /* NullGetterFunction.h */,
65525FC31A6DD3B3007B5495 /* NullSetterFunction.cpp */,
@@ -6369,6 +6381,7 @@
A552C3801ADDB8FE00139726 /* JSRemoteInspector.h in Headers */,
A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */,
BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */,
E33E8D1D1B9013C300346B52 /* JSNativeStdFunction.h in Headers */,
BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */,
1429D9300ED22D7000B89619 /* JIT.h in Headers */,
A5EA70E919F5B1010098F5EC /* AlternateDispatchableAgent.h in Headers */,
@@ -6729,6 +6742,7 @@
A1D792FD1B43864B004516F5 /* IntlNumberFormat.h in Headers */,
86AE64AA135E5E1C00963012 /* SH4Assembler.h in Headers */,
0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */,
E33E8D211B9013DE00346B52 /* NativeStdFunctionCell.h in Headers */,
0F2B670517B6B5AB00A7AE3F /* SimpleTypedArrayController.h in Headers */,
14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */,
0FB17661196B8F9E0091052A /* DFGHeapLocation.h in Headers */,
@@ -7675,6 +7689,7 @@
0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */,
140B7D1D0DC69AF7009C42B8 /* JSLexicalEnvironment.cpp in Sources */,
140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */,
E33E8D201B9013DE00346B52 /* NativeStdFunctionCell.cpp in Sources */,
C2CF39C116E15A8100DD69BE /* JSAPIWrapperObject.mm in Sources */,
147F39D0107EC37600427A48 /* JSArray.cpp in Sources */,
0F2B66E217B6B5AB00A7AE3F /* JSArrayBuffer.cpp in Sources */,
@@ -7901,6 +7916,7 @@
E3EF88741B66DF23003F26CB /* JSPropertyNameIterator.cpp in Sources */,
0F8F2B9E17306C8D007DBDA5 /* SourceCode.cpp in Sources */,
0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */,
E33E8D1C1B9013C300346B52 /* JSNativeStdFunction.cpp in Sources */,
E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */,
0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */,
0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */,
@@ -42,6 +42,7 @@
#include "JSInternalPromise.h"
#include "JSInternalPromiseDeferred.h"
#include "JSLock.h"
#include "JSNativeStdFunction.h"
#include "JSONObject.h"
#include "JSProxy.h"
#include "JSString.h"
@@ -1504,7 +1505,7 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
bool success = true;

#if ENABLE(ES6_MODULES)
JSFunction* errorHandler = JSFunction::create(vm, globalObject, 1, String(), [&](ExecState* exec) {
JSFunction* errorHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&](ExecState* exec) {
success = false;
dumpException(globalObject, exec->argument(0));
return JSValue::encode(jsUndefined());
@@ -40,11 +40,6 @@ namespace JSC {

const ClassInfo JSArrowFunction::s_info = { "ArrowFunction", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArrowFunction) };

void JSArrowFunction::destroy(JSCell* cell)
{
static_cast<JSArrowFunction*>(cell)->JSArrowFunction::~JSArrowFunction();
}

JSArrowFunction* JSArrowFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope, JSValue boundThis)
{
JSArrowFunction* result = createImpl(vm, executable, scope, boundThis);
@@ -48,8 +48,6 @@ class JSArrowFunction : public JSFunction {
static JSArrowFunction* create(VM&, FunctionExecutable*, JSScope*, JSValue);
static JSArrowFunction* createWithInvalidatedReallocationWatchpoint(VM&, FunctionExecutable*, JSScope*, JSValue);

static void destroy(JSCell*);

static size_t allocationSize(size_t inlineCapacity)
{
ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
@@ -77,7 +77,7 @@ JSFunction* JSFunction::create(VM& vm, WebAssemblyExecutable* executable, JSScop
}
#endif

static inline NativeExecutable* getNativeExecutable(VM& vm, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
NativeExecutable* JSFunction::lookUpOrCreateNativeExecutable(VM& vm, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
{
#if !ENABLE(JIT)
UNUSED_PARAM(intrinsic);
@@ -92,38 +92,13 @@ static inline NativeExecutable* getNativeExecutable(VM& vm, NativeFunction nativ

JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
{
NativeExecutable* executable = getNativeExecutable(vm, nativeFunction, intrinsic, nativeConstructor);
NativeExecutable* executable = lookUpOrCreateNativeExecutable(vm, nativeFunction, intrinsic, nativeConstructor);
JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, globalObject, globalObject->functionStructure());
// Can't do this during initialization because getHostFunction might do a GC allocation.
function->finishCreation(vm, executable, length, name);
return function;
}

class JSStdFunction : public JSFunction {
public:
JSStdFunction(VM& vm, JSGlobalObject* object, Structure* structure, NativeStdFunction&& function)
: JSFunction(vm, object, structure)
, stdFunction(WTF::move(function)) { }

NativeStdFunction stdFunction;
};

static EncodedJSValue JSC_HOST_CALL runStdFunction(ExecState* state)
{
JSStdFunction* jsFunction = jsCast<JSStdFunction*>(state->callee());
ASSERT(jsFunction);
return jsFunction->stdFunction(state);
}

JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeStdFunction&& nativeStdFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
{
NativeExecutable* executable = getNativeExecutable(vm, runStdFunction, intrinsic, nativeConstructor);
JSStdFunction* function = new (NotNull, allocateCell<JSStdFunction>(vm.heap)) JSStdFunction(vm, globalObject, globalObject->functionStructure(), WTF::move(nativeStdFunction));
// Can't do this during initialization because getHostFunction might do a GC allocation.
function->finishCreation(vm, executable, length, name);
return function;
}

JSFunction::JSFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure)
: Base(vm, globalObject, structure)
, m_executable()

0 comments on commit a961702

Please sign in to comment.