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) But, testkjs now has the following results: 19 tests fixed (good!), 104 regressions found 967 test(s) selected, 962 test(s) completed, 245 failures reported (25.46% failed) Of those 245, most are really buggy JavaScriptCore completely and totally dieing. But as can be seen, its almost ready for primetime. Alot of the code is ported over, and it works really nicely as long as the GC doesn't kick in. In fact, if anyone has alot of RAM handy (my 512 ain't enough :( ) on a Wintel machine, i'll send the source to them, and let them try running it w/o the GC enabled and see if its as stable as the OS X version. Reason alot of RAM? without that GC, some tests can use alot of RAM. the biggest ive seen was 450, XP promptly BSODed when it tried to use a tiny bit more (out of physical RAM, couldnt page ANYTHING else).
On 7/3/05, Justin Haygood <justin@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"); }
participants (2)
-
Justin Haygood
-
Krzysztof Kowalczyk