Ignore:
Timestamp:
Oct 23, 2008, 3:29:54 PM (17 years ago)
Author:
[email protected]
Message:

2008-10-23 Gavin Barraclough <[email protected]>

Reviewed by Oliver Hunt.

Fix hideous pathological case performance when looking up repatch info, bug #21727.

When repatching JIT code to optimize we look up records providing information about
the generated code (also used to track recsources used in linking to be later released).
The lookup was being performed using a linear scan of all such records.

(1) Split up the different types of reptach information. This means we can search them

separately, and in some cases should reduce their size.

(2) In the case of property accesses, search with a binary chop over the data.
(3) In the case of calls, pass a pointer to the repatch info into the relink function.

  • VM/CTI.cpp: (JSC::CTI::CTI): (JSC::CTI::compileOpCall): (JSC::CTI::privateCompileMainPass): (JSC::CTI::privateCompileSlowCases): (JSC::CTI::privateCompile): (JSC::CTI::unlinkCall): (JSC::CTI::linkCall):
  • VM/CTI.h:
  • VM/CodeBlock.cpp: (JSC::CodeBlock::dump): (JSC::CodeBlock::~CodeBlock): (JSC::CodeBlock::unlinkCallers): (JSC::CodeBlock::derefStructureIDs):
  • VM/CodeBlock.h: (JSC::StructureStubInfo::StructureStubInfo): (JSC::CallLinkInfo::CallLinkInfo): (JSC::CallLinkInfo::setUnlinked): (JSC::CallLinkInfo::isLinked): (JSC::getStructureStubInfoReturnLocation): (JSC::binaryChop): (JSC::CodeBlock::addCaller): (JSC::CodeBlock::getStubInfo):
  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::emitResolve): (JSC::CodeGenerator::emitGetById): (JSC::CodeGenerator::emitPutById): (JSC::CodeGenerator::emitCall): (JSC::CodeGenerator::emitConstruct):
  • VM/Machine.cpp: (JSC::Machine::cti_vm_lazyLinkCall):
File:
1 edited

Legend:

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

    r37804 r37831  
    276276    }
    277277
    278     if (structureIDInstructions.size()) {
     278    if (globalResolveInstructions.size() || propertyAccessInstructions.size())
    279279        printf("\nStructureIDs:\n");
     280
     281    if (globalResolveInstructions.size()) {
    280282        size_t i = 0;
    281283        do {
    282              printStructureIDs(&instructions[structureIDInstructions[i].opcodeIndex]);
     284             printStructureIDs(&instructions[globalResolveInstructions[i]]);
    283285             ++i;
    284         } while (i < structureIDInstructions.size());
     286        } while (i < globalResolveInstructions.size());
     287    }
     288    if (propertyAccessInstructions.size()) {
     289        size_t i = 0;
     290        do {
     291             printStructureIDs(&instructions[propertyAccessInstructions[i].opcodeIndex]);
     292             ++i;
     293        } while (i < propertyAccessInstructions.size());
    285294    }
    286295 
     
    942951CodeBlock::~CodeBlock()
    943952{
    944     size_t size = structureIDInstructions.size();
    945     for (size_t i = 0; i < size; ++i) {
    946         derefStructureIDs(&instructions[structureIDInstructions[i].opcodeIndex]);
    947         if (structureIDInstructions[i].stubRoutine)
    948             WTF::fastFreeExecutable(structureIDInstructions[i].stubRoutine);
    949         if (CallLinkInfo* callLinkInfo = structureIDInstructions[i].linkInfoPtr) {
     953    for (size_t size = globalResolveInstructions.size(), i = 0; i < size; ++i) {
     954        derefStructureIDs(&instructions[globalResolveInstructions[i]]);
     955    }
     956
     957    for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
     958        derefStructureIDs(&instructions[propertyAccessInstructions[i].opcodeIndex]);
     959        if (propertyAccessInstructions[i].stubRoutine)
     960            WTF::fastFreeExecutable(propertyAccessInstructions[i].stubRoutine);
     961    }
     962
     963    for (size_t size = callLinkInfos.size(), i = 0; i < size; ++i) {
     964        CallLinkInfo* callLinkInfo = &callLinkInfos[i];
     965        if (callLinkInfo->isLinked())
    950966            callLinkInfo->callee->removeCaller(callLinkInfo);
    951             delete callLinkInfo;
    952         }
    953967    }
    954968
     
    967981    for (size_t i = 0; i < size; ++i) {
    968982        CallLinkInfo* currentCaller = linkedCallerList[i];
    969         CTI::unlinkCall(currentCaller->callerStructureStubInfo);
    970         currentCaller->callerStructureStubInfo->linkInfoPtr = 0;
    971         delete currentCaller;
     983        CTI::unlinkCall(currentCaller);
     984        currentCaller->setUnlinked();
    972985    }
    973986    linkedCallerList.clear();
     
    10101023   
    10111024    // These instructions don't ref their StructureIDs.
    1012     ASSERT(vPC[0].u.opcode == machine->getOpcode(op_get_by_id) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id) || vPC[0].u.opcode == machine->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_get_array_length) || vPC[0].u.opcode == machine->getOpcode(op_get_string_length)
    1013         || vPC[0].u.opcode == machine->getOpcode(op_call_eval) || vPC[0].u.opcode == machine->getOpcode(op_call) || vPC[0].u.opcode == machine->getOpcode(op_construct));
     1025    ASSERT(vPC[0].u.opcode == machine->getOpcode(op_get_by_id) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id) || vPC[0].u.opcode == machine->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_get_array_length) || vPC[0].u.opcode == machine->getOpcode(op_get_string_length));
    10141026}
    10151027
Note: See TracChangeset for help on using the changeset viewer.