libjit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Libjit] RFC: type safety


From: Alexey Galakhov
Subject: Re: [Libjit] RFC: type safety
Date: Thu, 28 Feb 2013 17:02:50 +0600
User-agent: Mozilla/5.0 (X11; Linux i686; rv:10.0.12) Gecko/20130116 Icedove/10.0.12

Hi Aleksey,

> Thanks to your and a couple of other people requests I am going to resume
> my work on it now.

Thank you for supporting libjit. IMHO it is the only library providing
easy to use general-purpose JIT. LLVM is popular but its interface is
quite hard to understand and its C++ so it cannot be used easily from C
code. Also LLVM seems to have random failures while libjit (hopefully)
doesn't. I'd like to help improving libjit as much as possible.

> Concerning your proposal for introducing fake struct declarations I think that
> having these types declared as void* more clearly states their purpose -
> to be defined by the concrete memory plugin. Any kind of misuse would be
> detected quickly on first tests. The sad fact that you had to spend few days
> on debugging is because this was a new interface that was not yet fully
> tested.

I cannot agree with that, and here's why. First, it is known that some
branches or, even worse, combinations of branches are very rare. Even if
using gcov for coverage testing, one may have a variable assigned in one
place and then read in another place with 2^-20 probability or such.
This is unlikely to be covered in synthetic tests but is quite likely to
happen in real life. That's why compiler's checks are very important.

Second, void* is more like "raw memory for general use", that's what
malloc() returns. A pointer to a specific structure of unknown type and
size should have its own name. In a language like C++ one would probably
write like that:

class IFunctionInfo {
    virtual void* get_function_end() const = 0;
};

class CacheNode : public IFunctionInfo { ... our implementation ... };

The closest C equivalent to that is:

void* jit_get_function_end(IFunctionInfo* func_info) {
    CacheNode* node = (CacheNode* info);
    ...
}

Another possible approach is container_of() as in Linux kernel, like that:

struct jit_function_info { };

struct jit_cache_node
{
    struct jit_function_info info;
};

node = container_of(func_info, struct jit_cache_node, info);

This approach is well-proven and robust as well.

I think the code should be protected against human errors a little bit
more than jist by careful testing :) Here in Yandex we work literally
with streams of hunderds of gigabytes of data, so even failure
probability 2^-32 is considered high. That's why I am very cautious
about compile time checks.

BTW, I tried to compile with -Werror. Most of the warnings are harmless
but there are some that I really dislike. I'm examining if there are
real errors or not.

Regards,
Alex



reply via email to

[Prev in Thread] Current Thread [Next in Thread]