예제 #1
0
MacroAssemblerCodePtr StructureStubInfo::addAccessCase(
    CodeBlock* codeBlock, const Identifier& ident, std::unique_ptr<AccessCase> accessCase)
{
    VM& vm = *codeBlock->vm();
    
    if (!accessCase)
        return MacroAssemblerCodePtr();
    
    if (cacheType == CacheType::Stub)
        return u.stub->regenerateWithCase(vm, codeBlock, *this, ident, WTFMove(accessCase));

    std::unique_ptr<PolymorphicAccess> access = std::make_unique<PolymorphicAccess>();
    
    Vector<std::unique_ptr<AccessCase>> accessCases;
    
    std::unique_ptr<AccessCase> previousCase =
        AccessCase::fromStructureStubInfo(vm, codeBlock, *this);
    if (previousCase)
        accessCases.append(WTFMove(previousCase));

    accessCases.append(WTFMove(accessCase));

    MacroAssemblerCodePtr result =
        access->regenerateWithCases(vm, codeBlock, *this, ident, WTFMove(accessCases));

    if (!result)
        return MacroAssemblerCodePtr();

    initStub(codeBlock, WTFMove(access));
    return result;
}
예제 #2
0
AccessGenerationResult StructureStubInfo::addAccessCase(
    CodeBlock* codeBlock, const Identifier& ident, std::unique_ptr<AccessCase> accessCase)
{
    VM& vm = *codeBlock->vm();
    
    if (verbose)
        dataLog("Adding access case: ", accessCase, "\n");
    
    if (!accessCase)
        return AccessGenerationResult::GaveUp;
    
    AccessGenerationResult result;
    
    if (cacheType == CacheType::Stub) {
        result = u.stub->addCase(vm, codeBlock, *this, ident, WTFMove(accessCase));
        
        if (verbose)
            dataLog("Had stub, result: ", result, "\n");

        if (!result.buffered()) {
            bufferedStructures.clear();
            return result;
        }
    } else {
        std::unique_ptr<PolymorphicAccess> access = std::make_unique<PolymorphicAccess>();
        
        Vector<std::unique_ptr<AccessCase>, 2> accessCases;
        
        std::unique_ptr<AccessCase> previousCase =
            AccessCase::fromStructureStubInfo(vm, codeBlock, *this);
        if (previousCase)
            accessCases.append(WTFMove(previousCase));
        
        accessCases.append(WTFMove(accessCase));
        
        result = access->addCases(vm, codeBlock, *this, ident, WTFMove(accessCases));
        
        if (verbose)
            dataLog("Created stub, result: ", result, "\n");

        if (!result.buffered()) {
            bufferedStructures.clear();
            return result;
        }
        
        initStub(codeBlock, WTFMove(access));
    }
    
    RELEASE_ASSERT(!result.generatedSomeCode());
    
    // If we didn't buffer any cases then bail. If this made no changes then we'll just try again
    // subject to cool-down.
    if (!result.buffered()) {
        if (verbose)
            dataLog("Didn't buffer anything, bailing.\n");
        bufferedStructures.clear();
        return result;
    }
    
    // The buffering countdown tells us if we should be repatching now.
    if (bufferingCountdown) {
        if (verbose)
            dataLog("Countdown is too high: ", bufferingCountdown, ".\n");
        return result;
    }
    
    // Forget the buffered structures so that all future attempts to cache get fully handled by the
    // PolymorphicAccess.
    bufferedStructures.clear();
    
    result = u.stub->regenerate(vm, codeBlock, *this, ident);
    
    if (verbose)
        dataLog("Regeneration result: ", result, "\n");
    
    RELEASE_ASSERT(!result.buffered());
    
    if (!result.generatedSomeCode())
        return result;
    
    // If we generated some code then we don't want to attempt to repatch in the future until we
    // gather enough cases.
    bufferingCountdown = Options::repatchBufferingCountdown();
    return result;
}