Changeset 38652 in webkit for trunk/JavaScriptCore/bytecode


Ignore:
Timestamp:
Nov 20, 2008, 9:04:19 PM (17 years ago)
Author:
[email protected]
Message:

2008-11-19 Gavin Barraclough <[email protected]>

Reviewed by Darin Adler.

Add support for (really) polymorphic caching of prototype accesses.


If a cached prototype access misses, cti_op_get_by_id_proto_list is called.
When this occurs the Structure pointers from the instruction stream are copied
off into a new ProtoStubInfo object. A second prototype access trampoline is
generated, and chained onto the first. Subsequent missed call to
cti_op_get_by_id_proto_list_append, which append futher new trampolines, up to
PROTOTYPE_LIST_CACHE_SIZE (currently 4). If any of the misses result in an
access other than to a direct prototype property, list formation is halted (or
for the initial miss, does not take place at all).

Separate fail case functions are provided for each access since this contributes
to the performance progression (enables better processor branch prediction).

Overall this is a near 5% progression on v8, with around 10% wins on richards
and deltablue.

  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump): (JSC::CodeBlock::derefStructures):
  • bytecode/Instruction.h: (JSC::ProtoStructureList::ProtoStubInfo::set): (JSC::ProtoStructureList::ProtoStructureList): (JSC::Instruction::Instruction): (JSC::Instruction::):
  • bytecode/Opcode.h:
  • interpreter/Interpreter.cpp: (JSC::Interpreter::privateExecute): (JSC::Interpreter::tryCTICacheGetByID): (JSC::Interpreter::cti_op_put_by_id_fail): (JSC::Interpreter::cti_op_get_by_id_self_fail): (JSC::Interpreter::cti_op_get_by_id_proto_list): (JSC::Interpreter::cti_op_get_by_id_proto_list_append): (JSC::Interpreter::cti_op_get_by_id_proto_list_full): (JSC::Interpreter::cti_op_get_by_id_proto_fail): (JSC::Interpreter::cti_op_get_by_id_chain_fail): (JSC::Interpreter::cti_op_get_by_id_array_fail): (JSC::Interpreter::cti_op_get_by_id_string_fail):
  • interpreter/Interpreter.h:
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileGetByIdSelf): (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChain): (JSC::JIT::privateCompileCTIMachineTrampolines): (JSC::JIT::privateCompilePatchGetArrayLength):
  • jit/JIT.h: (JSC::JIT::compileGetByIdProtoList):
Location:
trunk/JavaScriptCore/bytecode
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecode/CodeBlock.cpp

    r38531 r38652  
    647647            break;
    648648        }
     649        case op_get_by_id_proto_list: {
     650            printGetByIdOp(location, it, identifiers, "op_get_by_id_proto_list");
     651            break;
     652        }
    649653        case op_get_by_id_chain: {
    650654            printGetByIdOp(location, it, identifiers, "get_by_id_chain");
     
    10201024        return;
    10211025    }
    1022    
     1026    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto_list)) {
     1027        PrototypeStructureList* prototypeStructures = vPC[4].u.prototypeStructure;
     1028        int count = vPC[5].u.operand;
     1029        for (int i = 0; i < count; ++i) {
     1030            PrototypeStructureList::ProtoStubInfo& info = prototypeStructures->list[i];
     1031            ASSERT(info.base);
     1032            ASSERT(info.proto);
     1033            ASSERT(info.stubRoutine);
     1034            info.base->deref();
     1035            info.proto->deref();
     1036            WTF::fastFreeExecutable(info.stubRoutine);
     1037        }
     1038        return;
     1039    }
     1040
    10231041    // These instructions don't ref their Structures.
    10241042    ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_get_array_length) || vPC[0].u.opcode == interpreter->getOpcode(op_get_string_length));
  • trunk/JavaScriptCore/bytecode/Instruction.h

    r38498 r38652  
    3434#include <wtf/VectorTraits.h>
    3535
     36#define PROTOTYPE_LIST_CACHE_SIZE 4
     37
    3638namespace JSC {
    3739
     
    3941    class Structure;
    4042    class StructureChain;
     43
     44    // Structure used by op_get_by_id_proto_list instruction to hold data off the main opcode stream.
     45    struct PrototypeStructureList {
     46        struct ProtoStubInfo {
     47            Structure* base;
     48            Structure* proto;
     49            int cachedOffset;
     50            void* stubRoutine;
     51           
     52            void set(Structure* _base, Structure* _proto, int _cachedOffset, void* _stubRoutine)
     53            {
     54                base = _base;
     55                proto = _proto;
     56                cachedOffset = _cachedOffset;
     57                stubRoutine = _stubRoutine;
     58            }
     59        } list[PROTOTYPE_LIST_CACHE_SIZE];
     60       
     61        PrototypeStructureList(Structure* firstBase, Structure* firstProto, int cachedOffset, void* stubRoutine)
     62        {
     63            list[0].set(firstBase, firstProto, cachedOffset, stubRoutine);
     64        }
     65    };
    4166
    4267    struct Instruction {
     
    5378        Instruction(StructureChain* structureChain) { u.structureChain = structureChain; }
    5479        Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
     80        Instruction(PrototypeStructureList* prototypeStructure) { u.prototypeStructure = prototypeStructure; }
    5581
    5682        union {
     
    6187            JSCell* jsCell;
    6288            ResultType::Type resultType;
     89            PrototypeStructureList* prototypeStructure;
    6390        } u;
    6491    };
  • trunk/JavaScriptCore/bytecode/Opcode.h

    r38498 r38652  
    103103        macro(op_get_by_id_self) \
    104104        macro(op_get_by_id_proto) \
     105        macro(op_get_by_id_proto_list) \
    105106        macro(op_get_by_id_chain) \
    106107        macro(op_get_by_id_generic) \
Note: See TracChangeset for help on using the changeset viewer.