Bug 25202: Improve performance of repeated callbacks into the VM
Reviewed by Cameron Zwarich
Add the concept of a CachedCall to native code for use in Array
prototype and similar functions where a single callback function
is called repeatedly with the same number of arguments.
Used Array.prototype.filter as the test function and got a 50% win
over a naive non-caching specialised version. This makes the native
implementation of Array.prototype.filter faster than the JS one once
more.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@42537 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/interpreter/Interpreter.h b/JavaScriptCore/interpreter/Interpreter.h
index dc3e617..b651b31 100644
--- a/JavaScriptCore/interpreter/Interpreter.h
+++ b/JavaScriptCore/interpreter/Interpreter.h
@@ -67,7 +67,7 @@
class Interpreter {
friend class JIT;
friend class JITStubs;
-
+ friend class CachedCall;
public:
Interpreter();
@@ -109,6 +109,36 @@
private:
enum ExecutionFlag { Normal, InitializeAndReturn };
+
+ struct CallFrameClosure {
+ CallFrame* oldCallFrame;
+ CallFrame* newCallFrame;
+ JSFunction* function;
+ CodeBlock* codeBlock;
+ JSGlobalData* globalData;
+ Register* oldEnd;
+ ScopeChainNode* scopeChain;
+ int expectedParams;
+ int providedParams;
+
+ void setArgument(int arg, JSValuePtr value)
+ {
+ if (arg < expectedParams)
+ newCallFrame[arg - RegisterFile::CallFrameHeaderSize - expectedParams] = value;
+ else
+ newCallFrame[arg - RegisterFile::CallFrameHeaderSize - expectedParams - providedParams] = value;
+ }
+ void resetCallFrame()
+ {
+ newCallFrame->setScopeChain(scopeChain);
+ newCallFrame->setCalleeArguments(0);
+ for (int i = providedParams; i < expectedParams; ++i)
+ newCallFrame[i - RegisterFile::CallFrameHeaderSize - expectedParams] = jsUndefined();
+ }
+ };
+ CallFrameClosure prepareForRepeatCall(FunctionBodyNode*, CallFrame*, JSFunction*, int argCount, ScopeChainNode*, JSValuePtr* exception);
+ void endRepeatCall(CallFrameClosure&);
+ JSValuePtr execute(CallFrameClosure&, JSValuePtr* exception);
NEVER_INLINE JSValuePtr callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset, JSValuePtr& exceptionValue);
JSValuePtr execute(EvalNode*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValuePtr* exception);
@@ -153,7 +183,7 @@
HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
#endif
};
-
+
} // namespace JSC
#endif // Interpreter_h