[webkit-dev] JavaScriptCore Win32 update

Krzysztof Kowalczyk kkowalczyk at gmail.com
Sun Jul 3 14:42:29 PDT 2005


On 7/3/05, Justin Haygood <justin at xiondigital.net> wrote:
> The conversative GC still appears to give problems, even though I
> narrowed it down, getting that stackbase pointer is tricky! Even using
> the register which supposedely stores it doesn't work, even tho the
> crash no longer appears in collector.cpp, it now appears in value.cpp
> (but i still believe it has to do with corruption caused by the GC)

When I was researching getting stack base on windows, I cobbled those
2 solution (using sources for various programs). I have no idea if
they're actually correct in multi-threaded programs, all I know that
in a simple test they give the same result that could be a stack base.

Another option would be to disable multi-threading on win. Original JS
wasn't multi-threaded, it's a fairly recent addition and I think
someone mentioned on this list that multi-threading isn't needed for
webcore per-se (could be wrong on that).

Krzysztof Kowalczyk | http://blog.kowalczyk.info

get_stack_base.cpp:

#include <windows.h>
#include <stdio.h>

typedef struct tagXTIB
{
//	EXCEPTION_REGISTRATION_RECORD* pvExcept; //00h Head of exception record list
	void * pvExcept; //00h Head of exception record list
	PVOID pvStackUserTop; //04 Top of user stack
	PVOID pvStackUserBase; //08h Base of user stack
} xTib;

static xTib* GetTIB()
{
    xTib* pTib;
    __asm
    {
        MOV EAX , FS:[18h]
        MOV pTib , EAX
    }
    return pTib;
}

void doTib()
{
    xTib *tib = GetTIB();
    printf("stack    top: 0x%lx\n", tib->pvStackUserTop);
    printf("stack bottom: 0x%lx\n", tib->pvStackUserTop);
}

NT_TIB* GetTIB2()
{
    NT_TIB* pTib;
    __asm
    {
        MOV EAX , FS:[18h]
        MOV pTib , EAX
    }
    return pTib;
}

void doTib2()
{
    NT_TIB *tib = GetTIB2();
    printf("stack  limit: 0x%lx\n", tib->StackLimit);
    printf("stack bottom: 0x%lx\n", tib->StackBase);
}

# define is_writable(prot) ((prot) == PAGE_READWRITE \
			    || (prot) == PAGE_WRITECOPY \
			    || (prot) == PAGE_EXECUTE_READWRITE \
			    || (prot) == PAGE_EXECUTE_WRITECOPY)

typedef unsigned long word;
typedef char * ptr_t;

/* Return the number of bytes that are writable starting at p.	*/
/* The pointer p is assumed to be page aligned.			*/
/* If base is not 0, *base becomes the beginning of the 	*/
/* allocation region containing p.				*/
word GC_get_writable_length(ptr_t p, ptr_t *base)
{
    MEMORY_BASIC_INFORMATION buf;
    word result;
    word protect;
    
    result = VirtualQuery(p, &buf, sizeof(buf));
    if (result != sizeof(buf))
    {
        printf("Weird VirtualQuery result\n");
        return 0;
    }
    if (base != 0) *base = (ptr_t)(buf.AllocationBase);
    protect = (buf.Protect & ~(PAGE_GUARD | PAGE_NOCACHE));
    if (!is_writable(protect)) {
        return(0);
    }
    if (buf.State != MEM_COMMIT) return(0);
    return(buf.RegionSize);
}

word GC_page_size;

void GC_setpagesize()
{
    SYSTEM_INFO GC_sysinfo;
    GetSystemInfo(&GC_sysinfo);
    GC_page_size = GC_sysinfo.dwPageSize;
}

ptr_t GC_get_stack_base()
{
    int dummy;

    /* PLTSCHEME: set page size if it's not ready (so I can use this
     function before a GC happens). */
    if (!GC_page_size) 
    GC_setpagesize();
    
    ptr_t sp = (ptr_t)(&dummy);
    ptr_t trunc_sp = (ptr_t)((word)sp & ~(GC_page_size - 1));
    word size = GC_get_writable_length(trunc_sp, 0);

    return(trunc_sp + size);    
}

void doMzGc()
{
    printf("stack   base: 0x%lx\n", GC_get_stack_base());
}

#if 0
ptr_t GetThreadStackBase(HANDLE hThread)
    CONTEXT context;
    LDT_ENTRY desc;
    void *base;
    DWORD size, read;
    NT_TIB tib;

    GetThreadContext(hThread, &context);
    GetThreadSelectorEntry(hThread, context.SegFs, &desc);

    base = (void*) (desc.BaseLow |
        desc.HighWord.Bytes.BaseMid << 16 |
        desc.HighWord.Bytes.BaseHi << 24);
    size = desc.LimitLow | desc.HighWord.Bits.LimitHi;
    if (desc.HighWord.Bits.Granularity)
        size *= 4096;
    else
        size++;

    ReadProcessMemory(hProcess, base, &tib, min(size, sizeof(tib)), &read);
    return (ptr_t)tib.StackBase;  // also tib.StackLimit
}
#endif

int main(int argc, char **argv)
{
    printf("start\n");

    printf("using TIB method\n");
    doTib();

    printf("using TIB2 method\n");
    doTib2();

    printf("using mzscheme method\n");
    doMzGc();

    printf("end\n");
}



More information about the webkit-dev mailing list