[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