summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSFunction.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:09:45 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:10:13 +0100
commit470286ecfe79d59df14944e5b5d34630fc739391 (patch)
tree43983212872e06cebefd2ae474418fa2908ca54c /Source/JavaScriptCore/runtime/JSFunction.cpp
parent23037105e948c2065da5a937d3a2396b0ff45c1e (diff)
downloadqtwebkit-470286ecfe79d59df14944e5b5d34630fc739391.tar.gz
Imported WebKit commit e89504fa9195b2063b2530961d4b73dd08de3242 (http://svn.webkit.org/repository/webkit/trunk@135485)
Change-Id: I03774e5ac79721c13ffa30d152537a74d0b12e66 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSFunction.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp19
1 files changed, 17 insertions, 2 deletions
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 891a23930..0a98e7c13 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -48,8 +48,6 @@ EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec)
return throwVMError(exec, createNotAConstructorError(exec, exec->callee()));
}
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFunction);
-
const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFunction) };
bool JSFunction::isHostFunctionNonInline() const
@@ -76,10 +74,25 @@ JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, in
return function;
}
+void JSFunction::destroy(JSCell* cell)
+{
+ static_cast<JSFunction*>(cell)->JSFunction::~JSFunction();
+}
+
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
: Base(exec->globalData(), structure)
, m_executable()
, m_scope(exec->globalData(), this, globalObject)
+ // We initialize blind so that changes to the prototype after function creation but before
+ // the optimizer kicks in don't disable optimizations. Once the optimizer kicks in, the
+ // watchpoint will start watching and any changes will both force deoptimization and disable
+ // future attempts to optimize. This is necessary because we are guaranteed that the
+ // inheritorID is changed exactly once prior to optimizations kicking in. We could be
+ // smarter and count the number of times the prototype is clobbered and only optimize if it
+ // was clobbered exactly once, but that seems like overkill. In almost all cases it will be
+ // clobbered once, and if it's clobbered more than once, that will probably only occur
+ // before we started optimizing, anyway.
+ , m_inheritorIDWatchpoint(InitializedBlind)
{
}
@@ -340,6 +353,7 @@ void JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J
PropertySlot slot;
thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
thisObject->m_cachedInheritorID.clear();
+ thisObject->m_inheritorIDWatchpoint.notifyWrite();
// Don't allow this to be cached, since a [[Put]] must clear m_cachedInheritorID.
PutPropertySlot dontCache;
Base::put(thisObject, exec, propertyName, value, dontCache);
@@ -386,6 +400,7 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNa
PropertySlot slot;
thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
thisObject->m_cachedInheritorID.clear();
+ thisObject->m_inheritorIDWatchpoint.notifyWrite();
return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
}