Ignore:
Timestamp:
Jan 5, 2009, 3:57:09 PM (16 years ago)
Author:
[email protected]
Message:

CanvasPixelArray performance is too slow
<https://bugs.webkit.org/show_bug.cgi?id=23123>

Reviewed by Gavin Barraclough

JavaScriptCore:
The fix to this is to devirtualise get and put in a manner similar to
JSString and JSArray. To do this I've added a ByteArray implementation
and JSByteArray wrapper to JSC. We can then do vptr comparisons to
devirtualise the calls.

This devirtualisation improves performance by 1.5-2x in my somewhat ad
hoc tests.

WebCore:
Remove the WebCore CanvasPixelArray implementation and replace
CPA usage with JSC::ByteArray. Replace the JSCanvasPixelArray
wrapper with an explicitly instantiated JSByteArray put on the
JSImageData object as an ordinary ReadOnly, DontDelete property.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/interpreter/Interpreter.cpp

    r39571 r39625  
    4141#include "JSActivation.h"
    4242#include "JSArray.h"
     43#include "JSByteArray.h"
    4344#include "JSFunction.h"
    4445#include "JSNotAnObject.h"
     
    607608    m_jsArrayVptr = jsArray->vptr();
    608609    jsArray->~JSCell();
     610
     611    JSByteArray* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
     612    m_jsByteArrayVptr = jsByteArray->vptr();
     613    jsByteArray->~JSCell();
    609614
    610615    JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
     
    28542859            } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
    28552860                result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
     2861            else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
     2862                result = asByteArray(baseValue)->getIndex(i);
    28562863            else
    28572864                result = baseValue->get(callFrame, i);
     
    28942901                else
    28952902                    jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue(callFrame));
     2903            } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
     2904                JSByteArray* jsByteArray = asByteArray(baseValue);
     2905                double dValue = 0;
     2906                JSValue* jsValue = callFrame[value].jsValue(callFrame);
     2907                if (JSImmediate::isNumber(jsValue))
     2908                    jsByteArray->setIndex(i, JSImmediate::getTruncatedInt32(jsValue));
     2909                else if (fastIsNumber(jsValue, dValue))
     2910                    jsByteArray->setIndex(i, dValue);
     2911                else
     2912                    baseValue->put(callFrame, i, jsValue);
    28962913            } else
    28972914                baseValue->put(callFrame, i, callFrame[value].jsValue(callFrame));
     
    50955112                result = jsArray->JSArray::get(callFrame, i);
    50965113        } else if (interpreter->isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
    5097             result = asString(baseValue)->getIndex(ARG_globalData, i);
     5114            return asString(baseValue)->getIndex(ARG_globalData, i);
     5115        else if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
     5116            return asByteArray(baseValue)->getIndex(i);
    50985117        else
    50995118            result = baseValue->get(callFrame, i);
     
    51885207            else
    51895208                jsArray->JSArray::put(callFrame, i, value);
     5209        } else if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
     5210            JSByteArray* jsByteArray = asByteArray(baseValue);
     5211            double dValue = 0;
     5212            if (JSImmediate::isNumber(value)) {
     5213                jsByteArray->setIndex(i, JSImmediate::getTruncatedInt32(value));
     5214                return;
     5215            } else if (fastIsNumber(value, dValue)) {
     5216                jsByteArray->setIndex(i, dValue);
     5217                return;
     5218            } else
     5219                baseValue->put(callFrame, i, value);
    51905220        } else
    51915221            baseValue->put(callFrame, i, value);
Note: See TracChangeset for help on using the changeset viewer.