harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ivan Volosyuk" <ivan.volos...@gmail.com>
Subject Re: [drlvm] The first GC helper with fast-path implemented in Java: gc_alloc
Date Wed, 11 Oct 2006 11:18:35 GMT
Mikhail, there is GC<>VM interface function exists for this purpose:

Boolean gc_supports_frontier_allocation(unsigned *offset_of_current,
unsigned *offset_of_limit) {
    // Need additional support for object offset in native stubs.
    *offset_of_current = field_offset(GC_Thread_Info, tls_current_free);
    *offset_of_limit = field_offset(GC_Thread_Info, tls_current_cleaned);
    return true;
}

1. VM exactly knows where the GC_Thread_Info is in TLS and using this
offsets can obtain current allocation position and its limit. It seems
that the information should be also propagated to JIT if you want to
implement the helper inlining.

2. You should not care about cleaned with uncleaned memory as it just
GC v4.1 specific optimization. Fast path should deal with current and
limit as in gc_supports_frontier_allocation().

3. This is just VM<>GC native interface function. There is no other
parameters passed here currently.

4. No need, see above (in 2).

5. Excellent idea! I thought about it. This optimization can be much valuable.

More issues to deal with.

Current native helper which is called from managed code to allocate a
object has one problem. It should call <clinit> for uninitialized
classes. I was working with it some time ago, but the change was too
intrusive and had negative performance impact. It was decided to do
this latter. I think we should think about it again now.

I suggest before compiling fast path code check whether class is
initialized and not finalizible. Depending on the results we can
produce different fast (or generic) code paths.

--
Ivan

On 10/11/06, Mikhail Fursov <mike.fursov@gmail.com> wrote:
> GC, VM gurus!
> I need your help in implementation of the first our helper written with
> magic.
> I've started with GCv41 allocation helper for objects.
> Please review the way I'm going to implement it and correct me if I have
> misunderstood something or confirm if everything is OK.
>
>
> The native fast path:
>
> Managed_Object_Handle gc_alloc_fast(unsigned in_size,  Allocation_Handle ah,
> void *thread_pointer) {
> C1.    assert((in_size % GC_OBJECT_ALIGNMENT) == 0);
> C2.    assert (ah);
> C3.    unsigned char *next;
>
> C4.    GC_Thread_Info *info = (GC_Thread_Info *) thread_pointer;
> C5.    Partial_Reveal_VTable *vtable = ah_to_vtable(ah);
> C6.    GC_VTable_Info *gcvt = vtable->get_gcvt();
> C7.    unsigned char *cleaned = info->tls_current_cleaned;
> C8.    unsigned char *res = info->tls_current_free;
>
> C9.    if (res + in_size <= cleaned) {
> C10.        if (gcvt->is_finalizible()) return 0;
>
> C11.        info->tls_current_free =  res + in_size;
> C12.        *(VT32*)res = ah;
>
> C13.        assert(((POINTER_SIZE_INT)res & (GC_OBJECT_ALIGNMENT - 1)) ==
> 0);
> C14.        return res;
> C15.    }
>
> C16.    if (gcvt->is_finalizible()) return 0;
>
> C17.    unsigned char *ceiling = info->tls_current_ceiling;
>
>
> C18.    if (res + in_size <= ceiling) {
>
> C19.        info->tls_current_free = next = info->tls_current_free +
> in_size;
>
>         // cleaning required
> C20.        unsigned char *cleaned_new = next +
> THREAD_LOCAL_CLEANED_AREA_SIZE;
> C21.        if (cleaned_new > ceiling) cleaned_new = ceiling;
> C22.        info->tls_current_cleaned = cleaned_new;
> C23.        memset(cleaned, 0, cleaned_new - cleaned);
> C24.        *(VT32*)res = ah;
>
> C25.        assert(((POINTER_SIZE_INT)res & (GC_OBJECT_ALIGNMENT - 1)) ==
> 0);
> C26.        return res;
> C27.    }
>
> C28.    return 0;
> }
>
>
>
> The helper's code:
>
> public static Object gc_alloc(int objSize, int allocationHandle) {
>
> J1.    Address tlsAddr = TLS.getGCThreadLocal();
>
> J2.    Address tlsCurrentFreeFieldAddr = tlsAddr.plus
> (TLS_CURRENT_FREE_OFFSET);
> J3.    Address tlsCurrentCleanedFieldAddr = tlsAddr.plus
> (TLS_CURRENT_CLEANED_OFFSET);
>
> J4.    Address tlsCurrentFreeAddr = tlsCurrentFreeFieldAddr.loadAddress();
> J5.    Address tlsCurrentCleanedAddr =
> tlsCurrentCleanedFieldAddr.loadAddress();
>
> J6.    Address tlsNewFreeAddr = tlsCurrentFreeAddr.plus(objSize);
>
>   // the fast path without cleaning
> J7.    if (tlsNewFreeAddr.LE(tlsCurrentCleanedAddr)) {
> J8.        tlsCurrentFreeFieldAddr.store(tlsNewFreeAddr);
> J9.        tlsCurrentFreeAddr.store(allocationHandle);
> J10.        return tlsCurrentFreeAddr;
> J11.    }
>
> J12.    Address tlsCurrentCeilingFieldAddr = tlsAddr.plus
> (TLS_CURRENT_CEILING_OFFSET);
> J13.    Address tlsCurrentCeilingAddr =
> tlsCurrentCeilingFieldAddr.loadAddress();
>
>         // the fast path with cleaning
> J14.   if (tlsNewCurrentFreeAddr.LE(tlsCurrentCeilingAddr)) {
> J15.       Address tlsNewCleanedAddr = tlsCurrentCeilingAddr;
> J16.       if (tlsCurrentCeilingAddr.diff(tlsNewFreeAddr) >
> THREAD_LOCAL_CLEANED_AREA_SIZE) {
> J17.           Address tlsCleanedNew = tlsNewFreeAddr.plus
> (THREAD_LOCAL_CLEANED_AREA_SIZE);
> J18.       }
> J19.       int bytesToClean = tlsNewCleanedAddr.diff(tlsNewFreeAddr);
> J20.       org.apache.harmony.vmhelper.native.Utils.memset(tlsNewFreeAddr,
> bytesToClean, 0);
> J21.       tlsCurrentCleanedFieldAddr.store(tlsNewCleanedAddr);
>
> J22.       tlsCurrentFreeFieldAddr.store(tlsNewFreeAddr);
> J23.       tlsCurrentFreeAddr.store(allocationHandle);
> J24.       return tlsCurrentFreeAddr;
>
>          }
>
>         //the slow path
>         //this call will be replaced by JIT with direct native call as VM
> magic
>         org.apache.harmony.vmhelper.native.DRLVMHelper.gc_alloc(objSize,
> allocationHandle);
>
> }
>
>
> The problems I see:
>
> 1) The problem: GC helper must know GC_Thread_Info struct offsets.
>
> 2) The problem: Where to keep GC magic code? This code is GC specific and
> must be available for bootstrap classloader.
> JIT can know all the details which magic code to inline (the helper type,
> the helper signature) from its properties (see opt.emconf file for example)
>
> 3) The problem: Is the signature for gc_alloc method : gc_alloc(int objSize,
> int allocationHandle) is universal for all GCs?
> I think it's not. But we can extend JIT with different signatures support if
> needed.
>
> 4) The new magic method is proposed, line J21:
> org.apache.harmony.vmhelper.native.Utils.memset(tlsNewFreeAddr,
> bytesToClean, 0);
>
> 5) The magic code in does not contain 'finalizable' check.
> JIT can do this check during the compilation and do not generate the fast
> path. This is another option to pass to JIT from GC.
>
> I've enumerated the lines in code if you want to comment it.
> Please feel free to review the code and to discuss any other problems I
> missed.
>
> --
> Mikhail Fursov

---------------------------------------------------------------------
Terms of use : http://incubator.apache.org/harmony/mailing.html
To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
For additional commands, e-mail: harmony-dev-help@incubator.apache.org


Mime
View raw message