void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
{
    if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) {
        CString name = callIdentifier.functionName().utf8();
        CString url = callIdentifier.url().utf8();
        JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber(), callIdentifier.columnNumber());
    }

    if (!m_origin)
        return;

    if (m_suspended)
        return;

    // Make a new node if the caller node has never seen this callee call frame before.
    // This can happen if |console.profile()| is called several frames deep in the call stack.
    ASSERT(m_currentNode);
    if (m_currentNode->callIdentifier() != callIdentifier) {
        RefPtr<ProfileNode> calleeNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
        beginCallEntry(calleeNode.get(), m_currentNode->lastCall().startTime());
        endCallEntry(calleeNode.get());
        m_currentNode->spliceNode(calleeNode.release());
        return;
    }

    endCallEntry(m_currentNode.get());
    m_currentNode = m_currentNode->parent();
}
void ProfileGenerator::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
{
    if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) {
        CString name = callIdentifier.functionName().utf8();
        CString url = callIdentifier.url().utf8();
        JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber(), callIdentifier.columnNumber());
    }

    if (!m_origin)
        return;

    if (m_suspended)
        return;

    RefPtr<ProfileNode> calleeNode = nullptr;

    // Find or create a node for the callee call frame.
    for (const RefPtr<ProfileNode>& child : m_currentNode->children()) {
        if (child->callIdentifier() == callIdentifier)
            calleeNode = child;
    }

    if (!calleeNode) {
        calleeNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
        m_currentNode->addChild(calleeNode);
    }

    m_currentNode = calleeNode;
    beginCallEntry(calleeNode.get(), m_stopwatch->elapsedTime());
}
void ProfileGenerator::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
{
    if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) {
        CString name = callIdentifier.functionName().utf8();
        CString url = callIdentifier.url().utf8();
        JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber(), callIdentifier.columnNumber());
    }

    if (!m_origin)
        return;

    ASSERT(m_currentNode);
    m_currentNode = m_currentNode->willExecute(callerCallFrame, callIdentifier);
}
void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
{
    if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) {
        CString name = callIdentifier.functionName().utf8();
        CString url = callIdentifier.url().utf8();
        JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber(), callIdentifier.columnNumber());
    }

    if (!m_origin)
        return;

    ASSERT(m_currentNode);
    if (m_currentNode->callIdentifier() != callIdentifier) {
        RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_head.get(), m_currentNode.get());
        returningNode->lastCall().setStartTime(m_currentNode->lastCall().startTime());
        returningNode->didExecute();
        m_currentNode->insertNode(returningNode.release());
        return;
    }

    m_currentNode = m_currentNode->didExecute();
}