Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
2011-05-19 Oliver Hunt <oliver@apple.com>
        Reviewed by Geoffrey Garen.

        Make Executables release their JIT code as soon as they become dead
        https://bugs.webkit.org/show_bug.cgi?id=61134

        Add an ability to clear an Executable's jit code without requiring
        it to be destroyed, and then call that from a finalizer.

        * heap/Weak.h:
        (JSC::Weak::Weak):
        (JSC::Weak::leak):
        * jit/JITCode.h:
        (JSC::JITCode::clear):
        * runtime/Executable.cpp:
        (JSC::ExecutableFinalizer::finalize):
        (JSC::ExecutableBase::executableFinalizer):
        * runtime/Executable.h:
        (JSC::ExecutableBase::ExecutableBase):
        (JSC::ExecutableBase::clearExecutableCode):

Canonical link: https://commits.webkit.org/76507@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@86883 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
ojhunt committed May 19, 2011
1 parent 734f283 commit 2bd7eeb
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 0 deletions.
22 changes: 22 additions & 0 deletions Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,25 @@
2011-05-19 Oliver Hunt <oliver@apple.com>

Reviewed by Geoffrey Garen.

Make Executables release their JIT code as soon as they become dead
https://bugs.webkit.org/show_bug.cgi?id=61134

Add an ability to clear an Executable's jit code without requiring
it to be destroyed, and then call that from a finalizer.

* heap/Weak.h:
(JSC::Weak::Weak):
(JSC::Weak::leak):
* jit/JITCode.h:
(JSC::JITCode::clear):
* runtime/Executable.cpp:
(JSC::ExecutableFinalizer::finalize):
(JSC::ExecutableBase::executableFinalizer):
* runtime/Executable.h:
(JSC::ExecutableBase::ExecutableBase):
(JSC::ExecutableBase::clearExecutableCode):

2011-05-19 Adam Roben <aroben@apple.com>

Remove a redundant and broken data export
Expand Down
1 change: 1 addition & 0 deletions Source/JavaScriptCore/heap/Handle.h
Expand Up @@ -47,6 +47,7 @@ template <> class Handle<JSValue>;
template<typename KeyType, typename MappedType, typename FinalizerCallback, typename HashArg, typename KeyTraitsArg> class WeakGCMap;

class HandleBase {
template <typename T> friend class Weak;
friend class HandleHeap;
friend struct JSCallbackObjectData;
template <typename KeyType, typename MappedType, typename FinalizerCallback, typename HashArg, typename KeyTraitsArg> friend class WeakGCMap;
Expand Down
6 changes: 6 additions & 0 deletions Source/JavaScriptCore/heap/HandleHeap.h
Expand Up @@ -70,6 +70,7 @@ class HandleHeap {

#if !ASSERT_DISABLED
bool hasWeakOwner(HandleSlot, WeakHandleOwner*);
bool hasFinalizer(HandleSlot);
#endif

unsigned protectedGlobalObjectCount();
Expand Down Expand Up @@ -197,6 +198,11 @@ inline bool HandleHeap::hasWeakOwner(HandleSlot handle, WeakHandleOwner* weakOwn
{
return toNode(handle)->weakOwner() == weakOwner;
}

inline bool HandleHeap::hasFinalizer(HandleSlot handle)
{
return toNode(handle)->weakOwner();
}
#endif

inline HandleHeap::Node::Node(HandleHeap* handleHeap)
Expand Down
15 changes: 15 additions & 0 deletions Source/JavaScriptCore/heap/Weak.h
Expand Up @@ -53,6 +53,13 @@ template <typename T> class Weak : public Handle<T> {
set(value);
}

enum AdoptTag { Adopt };
template<typename U> Weak(AdoptTag, Handle<U> handle)
: Handle<T>(handle.slot())
{
validateCell(get());
}

Weak(const Weak& other)
: Handle<T>()
{
Expand Down Expand Up @@ -121,6 +128,14 @@ template <typename T> class Weak : public Handle<T> {
setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
return *this;
}

HandleSlot leakHandle()
{
ASSERT(HandleHeap::heapFor(slot())->hasFinalizer(slot()));
HandleSlot result = slot();
setSlot(0);
return result;
}

private:
static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); }
Expand Down
6 changes: 6 additions & 0 deletions Source/JavaScriptCore/jit/JITCode.h
Expand Up @@ -101,6 +101,12 @@ namespace JSC {
return JITCode(code.dataLocation(), 0, 0);
}

void clear()
{
m_ref.~CodeRef();
new (&m_ref) CodeRef();
}

private:
JITCode(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size)
: m_ref(code, executablePool, size)
Expand Down
16 changes: 16 additions & 0 deletions Source/JavaScriptCore/runtime/Executable.cpp
Expand Up @@ -42,6 +42,22 @@ namespace JSC {

const ClassInfo ExecutableBase::s_info = { "Executable", 0, 0, 0 };

#if ENABLE(JIT)
class ExecutableFinalizer : public WeakHandleOwner {
virtual void finalize(Handle<Unknown> handle, void*)
{
Weak<ExecutableBase> executable(Weak<ExecutableBase>::Adopt, handle);
executable->clearExecutableCode();
}
};

WeakHandleOwner* ExecutableBase::executableFinalizer()
{
DEFINE_STATIC_LOCAL(ExecutableFinalizer, finalizer, ());
return &finalizer;
}
#endif

const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, 0 };

NativeExecutable::~NativeExecutable()
Expand Down
13 changes: 13 additions & 0 deletions Source/JavaScriptCore/runtime/Executable.h
Expand Up @@ -57,6 +57,10 @@ namespace JSC {
, m_numParametersForCall(numParameters)
, m_numParametersForConstruct(numParameters)
{
#if ENABLE(JIT)
Weak<ExecutableBase> finalizer(globalData, this, executableFinalizer());
finalizer.leakHandle();
#endif
}

bool isHostFunction() const
Expand Down Expand Up @@ -88,11 +92,20 @@ namespace JSC {
return m_jitCodeForConstruct;
}

void clearExecutableCode()
{
m_jitCodeForCall.clear();
m_jitCodeForConstruct.clear();
}

protected:
JITCode m_jitCodeForCall;
JITCode m_jitCodeForConstruct;
MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;
MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck;

private:
static WeakHandleOwner* executableFinalizer();
#endif
};

Expand Down

0 comments on commit 2bd7eeb

Please sign in to comment.