Ignore:
Timestamp:
Sep 20, 2009, 10:42:24 PM (16 years ago)
Author:
[email protected]
Message:

SNES is too slow
https://bugs.webkit.org/show_bug.cgi?id=29534

Reviewed by Maciej Stachowiak.

The problem was that the emulator used multiple classes with
more properties than our dictionary cutoff allowed, this resulted
in more or less all critical logic inside the emulator requiring
uncached property access.

Rather than simply bumping the dictionary cutoff, this patch
recognises that there are two ways to create a "dictionary"
structure. Either by adding a large number of properties, or
by removing a property. In the case of adding properties we
know all the existing properties will maintain their existing
offsets, so we could cache access to those properties, if we
know they won't be removed.

To make this possible, this patch adds the logic required to
distinguish a dictionary created by addition from one created
by removal. With this logic in place we can now cache access
to objects with large numbers of properties.

SNES performance improved by more than 6x.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JITStubs.cpp

    r48527 r48573  
    680680    Structure* structure = baseCell->structure();
    681681
    682     if (structure->isDictionary()) {
     682    if (structure->isUncacheableDictionary()) {
    683683        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
    684684        return;
     
    744744    Structure* structure = baseCell->structure();
    745745
    746     if (structure->isDictionary()) {
     746    if (structure->isUncacheableDictionary()) {
    747747        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
    748748        return;
     
    11551155    if (baseValue.isCell()
    11561156        && slot.isCacheable()
    1157         && !(structure = asCell(baseValue)->structure())->isDictionary()
     1157        && !(structure = asCell(baseValue)->structure())->isUncacheableDictionary()
    11581158        && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
    11591159        && specific
     
    12291229    if (baseValue.isCell()
    12301230        && slot.isCacheable()
    1231         && !asCell(baseValue)->structure()->isDictionary()
     1231        && !asCell(baseValue)->structure()->isUncacheableDictionary()
    12321232        && slot.slotBase() == baseValue) {
    12331233
     
    13001300    CHECK_FOR_EXCEPTION();
    13011301
    1302     if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
     1302    if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isUncacheableDictionary()) {
    13031303        ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
    13041304        return JSValue::encode(result);
     
    21892189    if (globalObject->getPropertySlot(callFrame, ident, slot)) {
    21902190        JSValue result = slot.getValue(callFrame, ident);
    2191         if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) {
     2191        if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
    21922192            GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
    21932193            if (globalResolveInfo.structure)
Note: See TracChangeset for help on using the changeset viewer.