void Disassembler::dumpHeader(PrintStream& out, LinkBuffer& linkBuffer)
{
    out.print("Generated DFG JIT code for ", CodeBlockWithJITType(m_graph.m_codeBlock, JITCode::DFGJIT), ", instruction count = ", m_graph.m_codeBlock->instructionCount(), ":\n");
    out.print("    Optimized with execution counter = ", m_graph.m_profiledBlock->jitExecuteCounter(), "\n");
    out.print("    Source: ", m_graph.m_codeBlock->sourceCodeOnOneLine(), "\n");
    out.print("    Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()), "):\n");
}
Exemple #2
0
void CallLinkInfo::visitWeak(RepatchBuffer& repatchBuffer)
{
    if (isLinked()) {
        if (stub) {
            if (!Heap::isMarked(stub->executable())) {
                if (Options::verboseOSR()) {
                    dataLog(
                        "Clearing closure call from ", *repatchBuffer.codeBlock(), " to ",
                        stub->executable()->hashFor(specializationKind()),
                        ", stub routine ", RawPointer(stub.get()), ".\n");
                }
                unlink(repatchBuffer);
            }
        } else if (!Heap::isMarked(callee.get())) {
            if (Options::verboseOSR()) {
                dataLog(
                    "Clearing call from ", *repatchBuffer.codeBlock(), " to ",
                    RawPointer(callee.get()), " (",
                    callee.get()->executable()->hashFor(specializationKind()),
                    ").\n");
            }
            unlink(repatchBuffer);
        }
    }
    if (!!lastSeenCallee && !Heap::isMarked(lastSeenCallee.get()))
        lastSeenCallee.clear();
}
Exemple #3
0
void CallLinkStatus::dump(PrintStream& out) const
{
    if (!isSet()) {
        out.print("Not Set");
        return;
    }
    
    CommaPrinter comma;
    
    if (m_isProved)
        out.print(comma, "Statically Proved");
    
    if (m_couldTakeSlowPath)
        out.print(comma, "Could Take Slow Path");
    
    if (m_callTarget)
        out.print(comma, "Known target: ", m_callTarget);
    
    if (m_executable) {
        out.print(comma, "Executable/CallHash: ", RawPointer(m_executable));
        if (!isCompilationThread())
            out.print("/", m_executable->hashFor(CodeForCall));
    }
    
    if (m_structure)
        out.print(comma, "Structure: ", RawPointer(m_structure));
}
void GetterSetterAccessCase::dumpImpl(PrintStream& out, CommaPrinter& comma) const
{
    Base::dumpImpl(out, comma);
    out.print(comma, "customSlotBase = ", RawPointer(customSlotBase()));
    if (callLinkInfo())
        out.print(comma, "callLinkInfo = ", RawPointer(callLinkInfo()));
    out.print(comma, "customAccessor = ", RawPointer(m_customAccessor.opaque));
}
Exemple #5
0
void AutomaticThread::start(const LockHolder&)
{
    RELEASE_ASSERT(m_isRunning);

    RefPtr<AutomaticThread> preserveThisForThread = this;

    m_hasUnderlyingThread = true;

    ThreadIdentifier thread = createThread(
                                  "WTF::AutomaticThread",
    [=] () {
        if (verbose)
            dataLog(RawPointer(this), ": Running automatic thread!\n");
        ThreadScope threadScope(preserveThisForThread);

        if (!ASSERT_DISABLED) {
            LockHolder locker(*m_lock);
            ASSERT(!m_condition->contains(locker, this));
        }

        auto stop = [&] (const LockHolder&) {
            m_isRunning = false;
            m_isRunningCondition.notifyAll();
        };

        for (;;) {
            {
                LockHolder locker(*m_lock);
                for (;;) {
                    PollResult result = poll(locker);
                    if (result == PollResult::Work)
                        break;
                    if (result == PollResult::Stop)
                        return stop(locker);
                    RELEASE_ASSERT(result == PollResult::Wait);
                    // Shut the thread down after one second.
                    bool awokenByNotify =
                        m_condition->m_condition.waitFor(*m_lock, 1_s);
                    if (!awokenByNotify) {
                        if (verbose)
                            dataLog(RawPointer(this), ": Going to sleep!\n");
                        m_condition->add(locker, this);
                        return;
                    }
                }
            }

            WorkResult result = work();
            if (result == WorkResult::Stop) {
                LockHolder locker(*m_lock);
                return stop(locker);
            }
            RELEASE_ASSERT(result == WorkResult::Continue);
        }
    });
    detachThread(thread);
}
Exemple #6
0
void logSanitizeStack(VM* vm)
{
    if (Options::verboseSanitizeStack() && vm->topCallFrame) {
        int dummy;
        dataLog(
            "Sanitizing stack with top call frame at ", RawPointer(vm->topCallFrame),
            ", current stack pointer at ", RawPointer(&dummy), ", in ",
            pointerDump(vm->topCallFrame->codeBlock()), " and last code origin = ",
            vm->topCallFrame->codeOrigin(), "\n");
    }
}
void MacroAssemblerCodePtr::dumpWithName(const char* name, PrintStream& out) const
{
    if (!m_value) {
        out.print(name, "(null)");
        return;
    }
    if (executableAddress() == dataLocation()) {
        out.print(name, "(", RawPointer(executableAddress()), ")");
        return;
    }
    out.print(name, "(executable = ", RawPointer(executableAddress()), ", dataLocation = ", RawPointer(dataLocation()), ")");
}
void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
{
    if (Options::breakOnThrow()) {
        CodeBlock* codeBlock = callFrame->codeBlock();
        if (codeBlock)
            dataLog("In call frame ", RawPointer(callFrame), " for code block ", *codeBlock, "\n");
        else
            dataLog("In call frame ", RawPointer(callFrame), " with null CodeBlock\n");
        CRASH();
    }
    
    ExecState* shadowChickenTopFrame = callFrame;
    if (unwindStart == UnwindFromCallerFrame) {
        VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame;
        shadowChickenTopFrame = callFrame->callerFrame(topVMEntryFrame);
    }
    vm->shadowChicken().log(*vm, shadowChickenTopFrame, ShadowChicken::Packet::throwPacket());
    
    Exception* exception = vm->exception();
    RELEASE_ASSERT(exception);
    HandlerInfo* handler = vm->interpreter->unwind(*vm, callFrame, exception, unwindStart); // This may update callFrame.

    void* catchRoutine;
    Instruction* catchPCForInterpreter = 0;
    if (handler) {
        // handler->target is meaningless for getting a code offset when catching
        // the exception in a DFG/FTL frame. This bytecode target offset could be
        // something that's in an inlined frame, which means an array access
        // with this bytecode offset in the machine frame is utterly meaningless
        // and can cause an overflow. OSR exit properly exits to handler->target
        // in the proper frame.
        if (!JITCode::isOptimizingJIT(callFrame->codeBlock()->jitType()))
            catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
#if ENABLE(JIT)
        catchRoutine = handler->nativeCode.executableAddress();
#else
        catchRoutine = catchPCForInterpreter->u.pointer;
#endif
    } else
        catchRoutine = LLInt::getCodePtr(handleUncaughtException);
    
    ASSERT(bitwise_cast<uintptr_t>(callFrame) < bitwise_cast<uintptr_t>(vm->topVMEntryFrame));

    vm->callFrameForCatch = callFrame;
    vm->targetMachinePCForThrow = catchRoutine;
    vm->targetInterpreterPCForThrow = catchPCForInterpreter;
    
    RELEASE_ASSERT(catchRoutine);
}
ObjectPropertyConditionSet generateConditionsForInstanceOf(
    VM& vm, JSCell* owner, ExecState* exec, Structure* headStructure, JSObject* prototype,
    bool shouldHit)
{
    bool didHit = false;
    if (ObjectPropertyConditionSetInternal::verbose)
        dataLog("Searching for prototype ", JSValue(prototype), " starting with structure ", RawPointer(headStructure), " with shouldHit = ", shouldHit, "\n");
    ObjectPropertyConditionSet result = generateConditions(
        vm, exec->lexicalGlobalObject(), headStructure, shouldHit ? prototype : nullptr,
        [&] (Vector<ObjectPropertyCondition>& conditions, JSObject* object) -> bool {
            if (ObjectPropertyConditionSetInternal::verbose)
                dataLog("Encountered object: ", RawPointer(object), "\n");
            if (object == prototype) {
                RELEASE_ASSERT(shouldHit);
                didHit = true;
                return true;
            }

            Structure* structure = object->structure(vm);
            if (structure->hasPolyProto())
                return false;
            conditions.append(
                ObjectPropertyCondition::hasPrototype(
                    vm, owner, object, structure->storedPrototypeObject()));
            return true;
        });
    if (result.isValid()) {
        if (ObjectPropertyConditionSetInternal::verbose)
            dataLog("didHit = ", didHit, ", shouldHit = ", shouldHit, "\n");
        RELEASE_ASSERT(didHit == shouldHit);
    }
    return result;
}
static CodeBlock* codeBlockFromArg(ExecState* exec)
{
    VM& vm = exec->vm();
    if (exec->argumentCount() < 1)
        return nullptr;

    JSValue value = exec->uncheckedArgument(0);
    CodeBlock* candidateCodeBlock = nullptr;
    if (value.isCell()) {
        JSFunction* func = jsDynamicCast<JSFunction*>(vm, value.asCell());
        if (func) {
            if (func->isHostFunction())
                candidateCodeBlock = nullptr;
            else
                candidateCodeBlock = func->jsExecutable()->eitherCodeBlock();
        }
    } else if (value.isDouble()) {
        // If the value is a double, it may be an encoded CodeBlock* that came from
        // $vm.codeBlockForFrame(). We'll treat it as a candidate codeBlock and check if it's
        // valid below before using.
        candidateCodeBlock = reinterpret_cast<CodeBlock*>(bitwise_cast<uint64_t>(value.asDouble()));
    }

    if (candidateCodeBlock && JSDollarVMPrototype::isValidCodeBlock(exec, candidateCodeBlock))
        return candidateCodeBlock;

    if (candidateCodeBlock)
        dataLog("Invalid codeBlock: ", RawPointer(candidateCodeBlock), " ", value, "\n");
    else
        dataLog("Invalid codeBlock: ", value, "\n");
    return nullptr;
}
void AdaptiveInferredPropertyValueWatchpoint::fire(const FireDetail& detail)
{
    // One of the watchpoints fired, but the other one didn't. Make sure that neither of them are
    // in any set anymore. This simplifies things by allowing us to reinstall the watchpoints
    // wherever from scratch.
    if (m_structureWatchpoint.isOnList())
        m_structureWatchpoint.remove();
    if (m_propertyWatchpoint.isOnList())
        m_propertyWatchpoint.remove();
    
    if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
        install();
        return;
    }
    
    if (DFG::shouldShowDisassembly()) {
        dataLog(
            "Firing watchpoint ", RawPointer(this), " (", m_key, ") on ", *m_codeBlock, "\n");
    }
    
    StringPrintStream out;
    out.print("Adaptation of ", m_key, " failed: ", detail);
    
    StringFireDetail stringDetail(out.toCString().data());
    
    m_codeBlock->jettison(
        Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization, &stringDetail);
}
Exemple #12
0
void Worklist::dump(const MutexLocker&, PrintStream& out) const
{
    out.print(
        "Worklist(", RawPointer(this), ")[Queue Length = ", m_queue.size(),
        ", Map Size = ", m_plans.size(), ", Num Ready = ", m_readyPlans.size(),
        ", Num Active Threads = ", m_numberOfActiveThreads, "/", m_threads.size(), "]");
}
Exemple #13
0
void HeapSnapshot::finalize()
{
    ASSERT(!m_finalized);
    m_finalized = true;

    // Nodes are appended to the snapshot in identifier order.
    // Now that we have the complete list of nodes we will sort
    // them in a different order. Remember the range of identifiers
    // in this snapshot.
    if (!isEmpty()) {
        m_firstObjectIdentifier = m_nodes.first().identifier;
        m_lastObjectIdentifier = m_nodes.last().identifier;
    }

    std::sort(m_nodes.begin(), m_nodes.end(), [] (const HeapSnapshotNode& a, const HeapSnapshotNode& b) {
        return a.cell < b.cell;
    });

#ifndef NDEBUG
    // Assert there are no duplicates or nullptr cells.
    JSCell* previousCell = nullptr;
    for (auto& node : m_nodes) {
        ASSERT(node.cell);
        ASSERT(!(reinterpret_cast<intptr_t>(node.cell) & CellToSweepTag));
        if (node.cell == previousCell) {
            dataLog("Seeing same cell twice: ", RawPointer(previousCell), "\n");
            ASSERT(node.cell != previousCell);
        }
        previousCell = node.cell;
    }
#endif
}
void CodeBlockJettisoningWatchpoint::fireInternal(VM&, const FireDetail& detail)
{
    if (DFG::shouldDumpDisassembly())
        dataLog("Firing watchpoint ", RawPointer(this), " on ", *m_codeBlock, "\n");

    m_codeBlock->jettison(Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization, &detail);
}
void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
{
    if (Options::breakOnThrow()) {
        dataLog("In call frame ", RawPointer(callFrame), " for code block ", *callFrame->codeBlock(), "\n");
        CRASH();
    }
    
    RELEASE_ASSERT(exceptionValue);
    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
    HandlerInfo* handler = vm->interpreter->unwind(vmEntryFrame, callFrame, exceptionValue); // This may update vmEntryFrame and callFrame.

    void* catchRoutine;
    Instruction* catchPCForInterpreter = 0;
    if (handler) {
        catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
#if ENABLE(JIT)
        catchRoutine = handler->nativeCode.executableAddress();
#else
        catchRoutine = catchPCForInterpreter->u.pointer;
#endif
    } else
        catchRoutine = LLInt::getCodePtr(handleUncaughtException);
    
    vm->vmEntryFrameForThrow = vmEntryFrame;
    vm->callFrameForThrow = callFrame;
    vm->targetMachinePCForThrow = catchRoutine;
    vm->targetInterpreterPCForThrow = catchPCForInterpreter;
    
    RELEASE_ASSERT(catchRoutine);
}
CString ArrayProfile::briefDescription(CodeBlock* codeBlock)
{
    computeUpdatedPrediction(codeBlock);
    
    StringPrintStream out;
    
    bool hasPrinted = false;
    
    if (m_observedArrayModes) {
        if (hasPrinted)
            out.print(", ");
        out.print(ArrayModesDump(m_observedArrayModes));
        hasPrinted = true;
    }
    
    if (structureIsPolymorphic()) {
        if (hasPrinted)
            out.print(", ");
        out.print("struct = TOP");
        hasPrinted = true;
    } else if (m_expectedStructure) {
        if (hasPrinted)
            out.print(", ");
        out.print("struct = ", RawPointer(m_expectedStructure));
        hasPrinted = true;
    }
    
    if (m_mayStoreToHole) {
        if (hasPrinted)
            out.print(", ");
        out.print("Hole");
        hasPrinted = true;
    }
    
    if (m_outOfBounds) {
        if (hasPrinted)
            out.print(", ");
        out.print("OutOfBounds");
        hasPrinted = true;
    }
    
    if (m_mayInterceptIndexedAccesses) {
        if (hasPrinted)
            out.print(", ");
        out.print("Intercept");
        hasPrinted = true;
    }
    
    if (m_usesOriginalArrayStructures) {
        if (hasPrinted)
            out.print(", ");
        out.print("Original");
        hasPrinted = true;
    }
    
    UNUSED_PARAM(hasPrinted);
    
    return out.toCString();
}
Exemple #17
0
AutomaticThread::AutomaticThread(const LockHolder& locker, Box<Lock> lock, RefPtr<AutomaticThreadCondition> condition)
    : m_lock(lock)
    , m_condition(condition)
{
    if (verbose)
        dataLog(RawPointer(this), ": Allocated AutomaticThread.\n");
    m_condition->add(locker, this);
}
Exemple #18
0
void Disassembler::dump(PrintStream& out, LinkBuffer& linkBuffer)
{
    m_graph.m_dominators.computeIfNecessary(m_graph);
    
    out.print("Generated DFG JIT code for ", CodeBlockWithJITType(m_graph.m_codeBlock, JITCode::DFGJIT), ", instruction count = ", m_graph.m_codeBlock->instructionCount(), ":\n");
    out.print("    Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()), "):\n");
    
    const char* prefix = "    ";
    const char* disassemblyPrefix = "        ";
    
    NodeIndex lastNodeIndex = NoNode;
    MacroAssembler::Label previousLabel = m_startOfCode;
    for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
        if (!block)
            continue;
        dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_labelForBlockIndex[blockIndex], lastNodeIndex);
        m_graph.dumpBlockHeader(out, prefix, blockIndex, Graph::DumpLivePhisOnly);
        NodeIndex lastNodeIndexForDisassembly = block->at(0);
        for (size_t i = 0; i < block->size(); ++i) {
            if (!m_graph[block->at(i)].willHaveCodeGenOrOSR() && !Options::showAllDFGNodes())
                continue;
            MacroAssembler::Label currentLabel;
            if (m_labelForNodeIndex[block->at(i)].isSet())
                currentLabel = m_labelForNodeIndex[block->at(i)];
            else {
                // Dump the last instruction by using the first label of the next block
                // as the end point. This case is hit either during peephole compare
                // optimizations (the Branch won't have its own label) or if we have a
                // forced OSR exit.
                if (blockIndex + 1 < m_graph.m_blocks.size())
                    currentLabel = m_labelForBlockIndex[blockIndex + 1];
                else
                    currentLabel = m_endOfMainPath;
            }
            dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, currentLabel, lastNodeIndexForDisassembly);
            m_graph.dumpCodeOrigin(out, prefix, lastNodeIndex, block->at(i));
            m_graph.dump(out, prefix, block->at(i));
            lastNodeIndex = block->at(i);
            lastNodeIndexForDisassembly = block->at(i);
        }
    }
    dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfMainPath, lastNodeIndex);
    out.print(prefix, "(End Of Main Path)\n");
    dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfCode, NoNode);
}
void BlockDirectory::stopAllocating()
{
    if (false)
        dataLog(RawPointer(this), ": BlockDirectory::stopAllocating!\n");
    m_localAllocators.forEach(
        [&] (LocalAllocator* allocator) {
            allocator->stopAllocating();
        });
}
void* prepareOSREntry(
    ExecState* exec, CodeBlock* dfgCodeBlock, CodeBlock* entryCodeBlock,
    unsigned bytecodeIndex, unsigned streamIndex)
{
    VM& vm = exec->vm();
    CodeBlock* baseline = dfgCodeBlock->baselineVersion();
    DFG::JITCode* dfgCode = dfgCodeBlock->jitCode()->dfg();
    ForOSREntryJITCode* entryCode = entryCodeBlock->jitCode()->ftlForOSREntry();
    
    if (Options::verboseOSR()) {
        dataLog(
            "FTL OSR from ", *dfgCodeBlock, " to ", *entryCodeBlock, " at bc#",
            bytecodeIndex, ".\n");
    }
    
    if (bytecodeIndex != entryCode->bytecodeIndex()) {
        if (Options::verboseOSR())
            dataLog("    OSR failed because we don't have an entrypoint for bc#", bytecodeIndex, "; ours is for bc#", entryCode->bytecodeIndex());
        return 0;
    }
    
    Operands<JSValue> values;
    dfgCode->reconstruct(
        exec, dfgCodeBlock, CodeOrigin(bytecodeIndex), streamIndex, values);
    
    if (Options::verboseOSR())
        dataLog("    Values at entry: ", values, "\n");
    
    for (int argument = values.numberOfArguments(); argument--;) {
        RELEASE_ASSERT(
            exec->r(virtualRegisterForArgument(argument).offset()).jsValue() == values.argument(argument));
    }
    
    RELEASE_ASSERT(
        static_cast<int>(values.numberOfLocals()) == baseline->m_numCalleeRegisters);
    
    EncodedJSValue* scratch = static_cast<EncodedJSValue*>(
        entryCode->entryBuffer()->dataBuffer());
    
    for (int local = values.numberOfLocals(); local--;)
        scratch[local] = JSValue::encode(values.local(local));
    
    int stackFrameSize = entryCode->common.requiredRegisterCountForExecutionAndExit();
    if (!vm.interpreter->stack().grow(&exec->registers()[virtualRegisterForLocal(stackFrameSize).offset()])) {
        if (Options::verboseOSR())
            dataLog("    OSR failed because stack growth failed.\n");
        return 0;
    }
    
    exec->setCodeBlock(entryCodeBlock);
    
    void* result = entryCode->addressForCall().executableAddress();
    if (Options::verboseOSR())
        dataLog("    Entry will succeed, going to address", RawPointer(result), "\n");
    
    return result;
}
Exemple #21
0
void Plan::run()
{
    if (verbose)
        dataLogLn("Starting plan.");
    {
        ModuleParser moduleParser(m_source, m_sourceLength);
        if (!moduleParser.parse()) {
            if (verbose)
                dataLogLn("Parsing module failed: ", moduleParser.errorMessage());
            m_errorMessage = moduleParser.errorMessage();
            return;
        }
        m_moduleInformation = WTFMove(moduleParser.moduleInformation());
    }
    if (verbose)
        dataLogLn("Parsed module.");

    if (!m_compiledFunctions.tryReserveCapacity(m_moduleInformation->functions.size())) {
        StringBuilder builder;
        builder.appendLiteral("Failed allocating enough space for ");
        builder.appendNumber(m_moduleInformation->functions.size());
        builder.appendLiteral(" compiled functions");
        m_errorMessage = builder.toString();
        return;
    }

    for (const FunctionInformation& info : m_moduleInformation->functions) {
        if (verbose)
            dataLogLn("Processing function starting at: ", info.start, " and ending at: ", info.end);
        const uint8_t* functionStart = m_source + info.start;
        size_t functionLength = info.end - info.start;
        ASSERT(functionLength <= m_sourceLength);

        String error = validateFunction(functionStart, functionLength, info.signature, m_moduleInformation->functions);
        if (!error.isNull()) {
            if (verbose) {
                for (unsigned i = 0; i < functionLength; ++i)
                    dataLog(RawPointer(reinterpret_cast<void*>(functionStart[i])), ", ");
                dataLogLn();
            }
            m_errorMessage = error;
            return;
        }

        m_compiledFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, m_moduleInformation->memory.get(), info.signature, m_moduleInformation->functions));
    }

    // Patch the call sites for each function.
    for (std::unique_ptr<FunctionCompilation>& functionPtr : m_compiledFunctions) {
        FunctionCompilation* function = functionPtr.get();
        for (auto& call : function->unlinkedCalls)
            MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(m_compiledFunctions[call.functionIndex]->code->code()));
    }

    m_failed = false;
}
JSValue OSRExitSite::toJS(ExecState* exec) const
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSArray* result = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, JSValue());
    for (unsigned i = 0; i < m_codeAddresses.size(); ++i)
        result->putDirectIndex(exec, i, jsString(exec, toString(RawPointer(m_codeAddresses[i]))));
    return result;
}
void IntendedStructureChain::dumpInContext(PrintStream& out, DumpContext* context) const
{
    out.print(
        "(global = ", RawPointer(m_globalObject), ", head = ",
        pointerDumpInContext(m_head, context), ", vector = [");
    CommaPrinter comma;
    for (unsigned i = 0; i < m_vector.size(); ++i)
        out.print(comma, pointerDumpInContext(m_vector[i], context));
    out.print("])");
}
Exemple #24
0
AutomaticThread::~AutomaticThread()
{
    if (verbose)
        dataLog(RawPointer(this), ": Deleting AutomaticThread.\n");
    LockHolder locker(*m_lock);
    
    // It's possible that we're in a waiting state with the thread shut down. This is a goofy way to
    // die, but it could happen.
    m_condition->remove(locker, this);
}
JSValue OSRExitSite::toJS(ExecState* exec) const
{
    VM& vm = exec->vm();
    JSArray* result = constructEmptyArray(exec, 0);
    if (UNLIKELY(vm.exception()))
        return jsUndefined();
    for (unsigned i = 0; i < m_codeAddresses.size(); ++i)
        result->putDirectIndex(exec, i, jsString(exec, toString(RawPointer(m_codeAddresses[i]))));
    return result;
}
void CodeBlockJettisoningWatchpoint::fireInternal()
{
    if (DFG::shouldShowDisassembly())
        dataLog("Firing watchpoint ", RawPointer(this), " on ", *m_codeBlock, "\n");

    m_codeBlock->jettison(CountReoptimization);

    if (isOnList())
        remove();
}
void JITDisassembler::dump(PrintStream& out, LinkBuffer& linkBuffer)
{
    out.print("Baseline JIT code for ", CodeBlockWithJITType(m_codeBlock, JITCode::BaselineJIT), ", instruction count = ", m_codeBlock->instructionCount(), "\n");
    out.print("   Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()), "):\n");
    dumpDisassembly(out, linkBuffer, m_startOfCode, m_labelForBytecodeIndexInMainPath[0]);
    
    MacroAssembler::Label firstSlowLabel;
    for (unsigned i = 0; i < m_labelForBytecodeIndexInSlowPath.size(); ++i) {
        if (m_labelForBytecodeIndexInSlowPath[i].isSet()) {
            firstSlowLabel = m_labelForBytecodeIndexInSlowPath[i];
            break;
        }
    }
    dumpForInstructions(out, linkBuffer, "    ", m_labelForBytecodeIndexInMainPath, firstSlowLabel.isSet() ? firstSlowLabel : m_endOfSlowPath);
    out.print("    (End Of Main Path)\n");
    dumpForInstructions(out, linkBuffer, "    (S) ", m_labelForBytecodeIndexInSlowPath, m_endOfSlowPath);
    out.print("    (End Of Slow Path)\n");

    dumpDisassembly(out, linkBuffer, m_endOfSlowPath, m_endOfCode);
}
Exemple #28
0
JSValue VM::throwException(ExecState* exec, JSValue error)
{
    if (Options::breakOnThrow()) {
        dataLog("In call frame ", RawPointer(exec), " for code block ", *exec->codeBlock(), "\n");
        CRASH();
    }

    ASSERT(exec == topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());

    Vector<StackFrame> stackTrace;
    interpreter->getStackTrace(stackTrace);
    m_exceptionStack = RefCountedArray<StackFrame>(stackTrace);
    m_exception = error;

    if (stackTrace.isEmpty() || !error.isObject())
        return error;
    JSObject* exception = asObject(error);

    StackFrame stackFrame;
    for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
        stackFrame = stackTrace.at(i);
        if (stackFrame.bytecodeOffset)
            break;
    }
    if (!hasErrorInfo(exec, exception)) {
        // FIXME: We should only really be adding these properties to VM generated exceptions,
        // but the inspector currently requires these for all thrown objects.
        unsigned line;
        unsigned column;
        stackFrame.computeLineAndColumn(line, column);
        exception->putDirect(*this, Identifier(this, "line"), jsNumber(line), ReadOnly | DontDelete);
        exception->putDirect(*this, Identifier(this, "column"), jsNumber(column), ReadOnly | DontDelete);
        if (!stackFrame.sourceURL.isEmpty())
            exception->putDirect(*this, Identifier(this, "sourceURL"), jsString(this, stackFrame.sourceURL), ReadOnly | DontDelete);
    }
    if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) {
        FindFirstCallerFrameWithCodeblockFunctor functor(exec);
        topCallFrame->iterate(functor);
        CallFrame* callFrame = functor.foundCallFrame();
        unsigned stackIndex = functor.index();

        if (callFrame && callFrame->codeBlock()) {
            stackFrame = stackTrace.at(stackIndex);
            appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), stackFrame.bytecodeOffset);
        }
    }

    if (exception->hasProperty(exec, this->propertyNames->stack))
        return error;

    exception->putDirect(*this, propertyNames->stack, interpreter->stackTraceAsString(topCallFrame, stackTrace), DontEnum);
    return error;
}
Exemple #29
0
void JSValue::dumpForBacktrace(PrintStream& out) const
{
    if (!*this)
        out.print("<JSValue()>");
    else if (isInt32())
        out.printf("%d", asInt32());
    else if (isDouble())
        out.printf("%lf", asDouble());
    else if (isCell()) {
        if (asCell()->inherits(JSString::info())) {
            JSString* string = jsCast<JSString*>(asCell());
            const StringImpl* impl = string->tryGetValueImpl();
            if (impl)
                out.print("\"", impl, "\"");
            else
                out.print("(unresolved string)");
        } else if (asCell()->inherits(Structure::info())) {
            out.print("Structure[ ", asCell()->structure()->classInfo()->className);
#if USE(JSVALUE64)
            out.print(" ID: ", asCell()->structureID());
#endif
            out.print("]: ", RawPointer(asCell()));
        } else {
            out.print("Cell[", asCell()->structure()->classInfo()->className);
#if USE(JSVALUE64)
            out.print(" ID: ", asCell()->structureID());
#endif
            out.print("]: ", RawPointer(asCell()));
        }
    } else if (isTrue())
        out.print("True");
    else if (isFalse())
        out.print("False");
    else if (isNull())
        out.print("Null");
    else if (isUndefined())
        out.print("Undefined");
    else
        out.print("INVALID");
}
void ShadowChicken::Packet::dump(PrintStream& out) const
{
    if (!*this) {
        out.print("empty");
        return;
    }
    
    if (isPrologue()) {
        out.print(
            "{callee = ", RawPointer(callee), ", frame = ", RawPointer(frame), ", callerFrame = ",
            RawPointer(callerFrame), "}");
        return;
    }
    
    if (isTail()) {
        out.print("tail:{frame = ", RawPointer(frame), "}");
        return;
    }
    
    ASSERT(isThrow());
    out.print("throw");
}