Changeset 42537 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Apr 15, 2009, 12:13:25 AM (16 years ago)
Author:
[email protected]
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/ArrayPrototype.cpp

    r41519 r42537  
    2626
    2727#include "CodeBlock.h"
     28#include "CachedCall.h"
    2829#include "Interpreter.h"
    2930#include "JIT.h"
     
    586587    unsigned filterIndex = 0;
    587588    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
    588     for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
    589         PropertySlot slot(thisObj);
    590 
    591         if (!thisObj->getPropertySlot(exec, k, slot))
    592             continue;
    593 
    594         JSValuePtr v = slot.getValue(exec, k);
    595 
    596         ArgList eachArguments;
    597 
    598         eachArguments.append(v);
    599         eachArguments.append(jsNumber(exec, k));
    600         eachArguments.append(thisObj);
    601 
    602         JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments);
    603 
    604         if (result.toBoolean(exec))
    605             resultArray->put(exec, filterIndex++, v);
     589    if (callType == CallTypeHost || !isJSArray(&exec->globalData(), thisObj) || !asArray(thisObj)->canGetIndex(length - 1)) {
     590        for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
     591            PropertySlot slot(thisObj);
     592           
     593            if (!thisObj->getPropertySlot(exec, k, slot))
     594                continue;
     595
     596            JSValuePtr v = slot.getValue(exec, k);
     597
     598            ArgList eachArguments;
     599
     600            eachArguments.append(v);
     601            eachArguments.append(jsNumber(exec, k));
     602            eachArguments.append(thisObj);
     603
     604            JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments);
     605
     606            if (result.toBoolean(exec))
     607                resultArray->put(exec, filterIndex++, v);
     608        }
     609    } else {
     610        JSFunction* f = asFunction(function);
     611        JSArray* array = asArray(thisObj);
     612        CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
     613        for (unsigned k = 0; k < length && !exec->hadException(); ++k) {           
     614            JSValuePtr v = array->getIndex(k);
     615            cachedCall.setThis(applyThis);
     616            cachedCall.setArgument(0, v);
     617            cachedCall.setArgument(1, jsNumber(exec, k));
     618            cachedCall.setArgument(2, thisObj);
     619
     620            JSValuePtr result = cachedCall.call();
     621            if (result.toBoolean(exec))
     622                resultArray->put(exec, filterIndex++, v);
     623        }
    606624    }
    607625    return resultArray;
Note: See TracChangeset for help on using the changeset viewer.