Ignore:
Timestamp:
Aug 28, 2015, 2:35:39 PM (10 years ago)
Author:
Yusuke Suzuki
Message:

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.

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.

(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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jsc.cpp

    r189086 r189124  
    4343#include "JSInternalPromiseDeferred.h"
    4444#include "JSLock.h"
     45#include "JSNativeStdFunction.h"
    4546#include "JSONObject.h"
    4647#include "JSProxy.h"
     
    15051506
    15061507#if ENABLE(ES6_MODULES)
    1507     JSFunction* errorHandler = JSFunction::create(vm, globalObject, 1, String(), [&](ExecState* exec) {
     1508    JSFunction* errorHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&](ExecState* exec) {
    15081509        success = false;
    15091510        dumpException(globalObject, exec->argument(0));
Note: See TracChangeset for help on using the changeset viewer.