Example #1
0
LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithDisassembly(const char* format, ...)
{
    CodeRef result = finalizeCodeWithoutDisassembly();

    if (m_alreadyDisassembled)
        return result;
    
    StringPrintStream out;
    out.printf("Generated JIT code for ");
    va_list argList;
    va_start(argList, format);
    out.vprintf(format, argList);
    va_end(argList);
    out.printf(":\n");

    out.printf("    Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
    
    CString header = out.toCString();
    
    if (Options::asyncDisassembly()) {
        disassembleAsynchronously(header, result, m_size, "    ");
        return result;
    }
    
    dataLog(header);
    disassemble(result.code(), m_size, "    ", WTF::dataFile());
    
    return result;
}
Example #2
0
LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithDisassembly(const char* format, ...)
{
    ASSERT(Options::showDisassembly() || Options::showDFGDisassembly());
    
    CodeRef result = finalizeCodeWithoutDisassembly();
    
    dataLogF("Generated JIT code for ");
    va_list argList;
    va_start(argList, format);
    WTF::dataLogFV(format, argList);
    va_end(argList);
    dataLogF(":\n");
    
    dataLogF("    Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
    disassemble(result.code(), m_size, "    ", WTF::dataFile());
    
    return result;
}
Example #3
0
void
Timers::deleteTimer (TimerKey const mt_nonnull timer_key)
{
    Timer * const timer = timer_key;

    if (timer->del_sbn) {
        CodeRef const code_ref = timer->timer_cb.getWeakCodeRef();
        if (!code_ref) {
          // doDeleteTimer() will be called by subscriberDeletionCallback,
          // which is likely just about to be called.
            return;
        }

        code_ref->removeDeletionCallback (timer->del_sbn);
    }

    doDeleteTimer (timer);
}
Example #4
0
LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithDisassembly(const char* format, ...)
{
    CodeRef result = finalizeCodeWithoutDisassembly();

#if ENABLE(DISASSEMBLER)
    dataLogF("Generated JIT code for ");
    va_list argList;
    va_start(argList, format);
    WTF::dataLogFV(format, argList);
    va_end(argList);
    dataLogF(":\n");
    
    dataLogF("    Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
    disassemble(result.code(), m_size, "    ", WTF::dataFile());
#else
    UNUSED_PARAM(format);
#endif // ENABLE(DISASSEMBLER)
    
    return result;
}
Example #5
0
void
Timers::processTimers ()
{
    Time const cur_time = getTimeMicroseconds ();

    mutex.lock ();

    TimerChain *chain = expiration_tree_leftmost;
    if (chain == NULL) {
	mutex.unlock ();
	return;
    }

    while (!chain->timer_list.isEmpty () && chain->nearest_time <= cur_time) {
	Time const cur_nearest_time = chain->nearest_time;

	logD (timers, _func, "cur_nearest_time: ", cur_nearest_time, ", cur_time: ", cur_time);

	Timer * const timer = chain->timer_list.getFirst ();
	assert (timer->active);
	chain->timer_list.remove (timer);

        bool delete_timer = false;
	if (timer->periodical) {
	    timer->due_time += chain->interval_microseconds;
	    if (timer->due_time < chain->interval_microseconds) {
		logW_ (_func, "Expiration time overflow");
		timer->due_time = (Time) -1;
	    }
	    chain->timer_list.append (timer);
	} else {
	    timer->active = false;

            if (timer->delete_after_tick) {
                if (timer->del_sbn) {
                    // TODO We create CodeRef twice: here and in call_unlocks_mutex_().
                    //      Should do this only once for efficiency.
                    CodeRef const code_ref = timer->timer_cb.getWeakCodeRef();
                    // If 'code_ref' is null, then doDeleteTimer() will be called
                    // by subscriberDeletionCallback(), which is likely just about
                    // to be called.
                    if (code_ref) {
                        code_ref->removeDeletionCallback (timer->del_sbn);
                        delete_timer = true;
                    }
                } else {
                    delete_timer = true;
                }
            }
	}

	bool delete_chain;
	if (chain->timer_list.isEmpty ()) {
	    expiration_tree.remove (chain);
	    expiration_tree_leftmost = expiration_tree.getLeftmost();
	    interval_tree.remove (chain);
	    delete_chain = true;
	} else {
	    if (cur_nearest_time != chain->timer_list.getFirst ()->due_time) {
		expiration_tree.remove (chain);
		chain->nearest_time = chain->timer_list.getFirst ()->due_time;
		expiration_tree.add (chain);
		expiration_tree_leftmost = expiration_tree.getLeftmost();
	    }
	    delete_chain = false;
	}

	timer->timer_cb.call_unlocks_mutex_ (mutex);

      // 'timer' might have been deleted by the user and should not be used
      // directly anymore.
      //
      // We can't delete the timer ourselves here for a similar reason: its
      // lifetime is controlled by the user, so we can't tie it to callback's
      // weak_obj.

        if (delete_timer)
            delete timer;

	if (delete_chain)
	    delete chain;

	mutex.lock ();

	// 'chain' might have been deleted due to user's actions in 'timer_cb' callback.
	chain = expiration_tree_leftmost;
	if (chain == NULL) {
	    mutex.unlock ();
	    return;
	}
    }

    mutex.unlock ();
}