listPo removeListEl(heapPo H, listPo list, integer px) { basePo base = C_BASE(list->base); int root = gcAddRoot(H, (ptrPo) (&base)); gcAddRoot(H, (ptrPo) (&list)); integer delta = base->length / 8; integer newLen = list->length + delta; basePo nb = (basePo) allocateObject(H, baseClass, BaseCellCount(newLen)); integer ocount = list->length; assert(ocount >= 0); integer extra = newLen - ocount; nb->min = extra / 2; nb->max = nb->min + ocount-1; nb->length = newLen; for (integer ix = 0; ix < px; ix++) { nb->els[nb->min + ix] = base->els[list->start + ix]; } for (integer ix = px + 1; ix < ocount; ix++) { nb->els[nb->min + ix] = base->els[list->start + ix]; } gcAddRoot(H, (ptrPo) (&nb)); listPo slice = (listPo) newSlice(H, nb, nb->min, list->length - 1); assert(saneList(H,slice)); gcReleaseRoot(H, root); releaseHeapLock(H); return slice; }
listPo replaceListEl(heapPo H, listPo list, integer px, termPo vl) { if (px >= listSize(list)) return appendToList(H, list, vl); else if (px < 0) return prependToList(H, list, vl); else { basePo base = C_BASE(list->base); int root = gcAddRoot(H, (ptrPo) (&base)); gcAddRoot(H, (ptrPo) (&list)); gcAddRoot(H, (ptrPo) (&vl)); integer delta = base->length / 8; basePo nb = copyBase(H, base, list->start, list->length, delta); nb->els[nb->min + px] = vl; gcAddRoot(H, (ptrPo) &nb); listPo slice = (listPo) newSlice(H, nb, nb->min, list->length); assert(saneList(H, slice)); gcReleaseRoot(H, root); releaseHeapLock(H); return slice; } }
listPo concatList(heapPo H, listPo l1, listPo l2) { integer len1 = l1->length; integer len2 = l2->length; if (len1 == 0) return l2; else if (len2 == 0) return l1; else { int root = gcAddRoot(H, (ptrPo) &l1); gcAddRoot(H, (ptrPo) (&l2)); integer llen = len1 + len2; listPo reslt = createList(H, llen + llen / 2); for (integer ix = 0; ix < len1; ix++) { reslt = addToList(H, reslt, nthEl(l1, ix)); } for (integer ix = 0; ix < len2; ix++) { reslt = addToList(H, reslt, nthEl(l2, ix)); } gcReleaseRoot(H, root); return reslt; } }
/* * This is here for convenience ... */ ptrI cmdLineOptions(heapPo H) { ptrI options = emptyList; rootPo root = gcAddRoot(H, &options); ptrI pair = kvoid; ptrI key = kvoid; ptrI val = kvoid; int i; gcAddRoot(H, &pair); gcAddRoot(H, &key); gcAddRoot(H, &val); for (i = 0; i < optCount; i++) { key = allocateInteger(H, Options[i].option); val = newEnumSym(Options[i].value); pair = tuplePair(H, key, val); options = consLsPair(H, pair, options); } gcRemoveRoot(H, root); return options; }
methodPo defineMtd(heapPo H, insPo ins, integer insCount, integer lclCount, integer stackDelta, labelPo lbl, normalPo pool, normalPo locals, normalPo lines) { int root = gcAddRoot(H, (ptrPo) &lbl); gcAddRoot(H, (ptrPo) &pool); gcAddRoot(H, (ptrPo) &locals); gcAddRoot(H, (ptrPo) &lines); methodPo mtd = (methodPo) allocateObject(H, methodClass, MtdCellCount(insCount)); for (integer ix = 0; ix < insCount; ix++) mtd->code[ix] = ins[ix]; mtd->codeSize = insCount; mtd->jit = Null; mtd->arity = lbl->arity; mtd->lclcnt = lclCount; mtd->pool = pool; mtd->locals = locals; mtd->lines = lines; mtd->stackDelta = stackDelta; lbl->mtd = mtd; gcReleaseRoot(H, root); return mtd; }
listPo appendToList(heapPo H, listPo list, termPo el) { basePo base = C_BASE(list->base); int root = gcAddRoot(H, (ptrPo) (&base)); gcAddRoot(H, (ptrPo) (&list)); gcAddRoot(H, (ptrPo) (&el)); if (base->max == list->start + list->length && base->max < base->length) { lockHeap(H); if (base->max == list->start + list->length && base->max < base->length) { // check after locking heap base->els[base->max++] = el; listPo slice = (listPo) newSlice(H, base, list->start, list->length + 1); gcReleaseRoot(H, root); releaseHeapLock(H); return slice; } releaseHeapLock(H); } basePo nb = copyBase(H, base, list->start, list->length, (list->length / 8) + 2); nb->els[nb->max++] = el; gcAddRoot(H, (ptrPo) (&nb)); listPo slice = (listPo) newSlice(H, nb, nb->min, nb->max - nb->min); gcReleaseRoot(H, root); return slice; }
listPo prependToList(heapPo H, listPo list, termPo el) { basePo base = C_BASE(list->base); int root = gcAddRoot(H, (ptrPo) (&base)); gcAddRoot(H, (ptrPo) (&list)); gcAddRoot(H, (ptrPo) (&el)); // logMsg(logFile, "list before prepend: %T", list); if (base->min == list->start && base->min > 0) { lockHeap(H); if (base->max == list->start && base->min > 0) { // check after locking heap base->els[--base->min] = el; listPo slice = (listPo) newSlice(H, base, list->start - 1, list->length + 1); gcReleaseRoot(H, root); releaseHeapLock(H); //logMsg(logFile, "slice after prepend: %T", slice); return slice; } releaseHeapLock(H); } basePo nb = copyBase(H, base, list->start, list->length, (list->length / 8) + 2); nb->els[--nb->min] = el; gcAddRoot(H, (ptrPo) (&nb)); listPo slice = (listPo) newSlice(H, nb, nb->min, list->length + 1); // logMsg(logFile, "slice post prepend: %T", slice); gcReleaseRoot(H, root); return slice; }
cellPo newCell(heapPo H, termPo content) { int root = gcAddRoot(H, (ptrPo) (&content)); cellPo cell = (cellPo) allocateObject(H, cellClass, CellCellCount); cell->content = content; gcReleaseRoot(H, root); return cell; }
termPo sliceList(heapPo H, listPo list, integer from, integer count) { assert(from >= 0 && from + count <= list->length); int root = gcAddRoot(H, (ptrPo) &list); listPo slice = (listPo) newSlice(H, C_BASE(list->base), list->start + from, count); gcReleaseRoot(H, root); return (termPo) slice; }
listPo insertListEl(heapPo H, listPo list, integer px, termPo vl) { basePo base = C_BASE(list->base); if (px <= 0) return prependToList(H, list, vl); else if (px >= listSize(list)) return appendToList(H, list, vl); else { int root = gcAddRoot(H, (ptrPo) (&base)); gcAddRoot(H, (ptrPo) (&list)); gcAddRoot(H, (ptrPo) (&vl)); integer delta = base->length / 8; integer newLen = base->length + delta + 1; basePo nb = (basePo) allocateObject(H, baseClass, BaseCellCount(newLen)); integer ocount = list->length; assert(ocount >= 0); integer extra = newLen - ocount; nb->min = extra / 2 - 1; nb->max = nb->min + ocount + 1; nb->length = newLen; for (integer ix = 0; ix < px; ix++) { nb->els[nb->min + ix] = base->els[base->min + ix]; } nb->els[nb->min + px] = vl; for (integer ix = px; ix < ocount; ix++) { nb->els[nb->min + ix + 1] = base->els[base->min + ix]; } gcAddRoot(H, (ptrPo) (&nb)); listPo slice = (listPo) newSlice(H, nb, nb->min, ocount + 1); gcReleaseRoot(H, root); releaseHeapLock(H); assert(saneList(H, slice)); return slice; } }
static termPo newSlice(heapPo H, basePo base, integer start, integer length) { int root = gcAddRoot(H, (ptrPo) &base); listPo slice = (listPo) allocateObject(H, listClass, ListCellCount); slice->base = (termPo) base; slice->start = start; slice->length = length; gcReleaseRoot(H, root); return (termPo) slice; }
listPo reverseList(heapPo H, listPo l1) { int root = gcAddRoot(H, (ptrPo) &l1); integer len = l1->length; listPo reslt = createList(H, len); for (integer ix = 1; ix <= len; ix++) { reslt = addToList(H, reslt, nthEl(l1, len - ix)); } gcReleaseRoot(H, root); return reslt; }
retCode g_envir(processPo P, ptrPo a) { extern char **environ; int i, cnt; ptrI lst = emptyList; ptrI el = kvoid; ptrI ky = kvoid; ptrI vl = kvoid; heapPo H = &P->proc.heap; rootPo root = gcAddRoot(H, &lst); gcAddRoot(H, &el); gcAddRoot(H, &ky); gcAddRoot(H, &vl); for (cnt = 0; environ[cnt] != NULL; cnt++); switchProcessState(P, in_exclusion); for (i = cnt - 1; i > 0; i--) { char *pt = strchr(environ[i], '='); if (pt != NULL) { *pt = '\0'; /* Split off the key from the value */ ky = allocateCString(H, environ[i]); vl = allocateCString(H, pt + 1); el = tuplePair(H,ky,vl); lst = consLsPair(H, el, lst); *pt = '='; /* restore the value */ } } setProcessRunnable(P); gcRemoveRoot(H, root); return equal(P, &lst, &a[1]); }
listPo createList(heapPo H, integer capacity) { listPo list = (listPo) allocateObject(H, listClass, ListCellCount); int root = gcAddRoot(H, (ptrPo) &list); integer extra = maximum(capacity / 8, 1); list->start = extra / 2; list->length = 0; list->base = voidEnum; basePo base = (basePo) allocateBase(H, capacity + extra, False); base->min = base->max = list->start; list->base = (termPo) base; gcReleaseRoot(H, root); return list; }
basePo copyBase(heapPo H, basePo ob, integer from, integer count, integer delta) { int root = gcAddRoot(H, (ptrPo) (&ob)); integer newLen = count + delta; basePo base = (basePo) allocateObject(H, baseClass, BaseCellCount(newLen)); base->min = delta / 2; base->max = base->min + count; for (integer ix = 0; ix < count; ix++) { base->els[base->min + ix] = ob->els[from + ix]; } base->length = newLen; gcReleaseRoot(H, root); return base; }
listPo allocateList(heapPo H, integer length, logical safeMode) { listPo list = (listPo) allocateObject(H, listClass, ListCellCount); int root = gcAddRoot(H, (ptrPo) &list); list->start = 0; list->length = length; list->base = voidEnum; integer extra = maximum(length / 8, 1); basePo base = (basePo) allocateBase(H, length + extra, safeMode); base->min = extra / 2; base->max = base->min + length; list->base = (termPo) base; list->start = base->min; gcReleaseRoot(H, root); return list; }
listPo flattenList(heapPo H, listPo l) { int root = gcAddRoot(H, (ptrPo) &l); integer llen = 0; processList(l, countEls, &llen); listPo reslt = createList(H, llen); for (integer ix = 0; ix < listSize(l); ix++) { listPo ll = C_LIST(nthEl(l, ix)); for (integer jx = 0; jx < listSize(ll); jx++) { reslt = addToList(H, reslt, nthEl(ll, jx)); } } assert(listSize(reslt) == llen); gcReleaseRoot(H, root); return reslt; }
jboolean rvmInitMemory(Env* env) { vm = env->vm; gcAddRoot(&referents); java_lang_ref_Reference_referent = rvmGetInstanceField(env, java_lang_ref_Reference, "referent", "Ljava/lang/Object;"); if (!java_lang_ref_Reference_referent) return FALSE; java_lang_ref_Reference_pendingNext = rvmGetInstanceField(env, java_lang_ref_Reference, "pendingNext", "Ljava/lang/ref/Reference;"); if (!java_lang_ref_Reference_pendingNext) return FALSE; java_lang_ref_Reference_queue = rvmGetInstanceField(env, java_lang_ref_Reference, "queue", "Ljava/lang/ref/ReferenceQueue;"); if (!java_lang_ref_Reference_queue) return FALSE; java_lang_ref_Reference_queueNext = rvmGetInstanceField(env, java_lang_ref_Reference, "queueNext", "Ljava/lang/ref/Reference;"); if (!java_lang_ref_Reference_queueNext) return FALSE; java_lang_ref_PhantomReference = rvmFindClassUsingLoader(env, "java/lang/ref/PhantomReference", NULL); if (!java_lang_ref_PhantomReference) return FALSE; java_lang_ref_WeakReference = rvmFindClassUsingLoader(env, "java/lang/ref/WeakReference", NULL); if (!java_lang_ref_WeakReference) return FALSE; java_lang_ref_SoftReference = rvmFindClassUsingLoader(env, "java/lang/ref/SoftReference", NULL); if (!java_lang_ref_SoftReference) return FALSE; java_lang_ref_FinalizerReference = rvmFindClassUsingLoader(env, "java/lang/ref/FinalizerReference", NULL); if (!java_lang_ref_FinalizerReference) return FALSE; java_lang_ref_FinalizerReference_add = rvmGetClassMethod(env, java_lang_ref_FinalizerReference, "add", "(Ljava/lang/Object;)V"); if (!java_lang_ref_FinalizerReference_add) return FALSE; java_lang_ref_FinalizerReference_zombie = rvmGetInstanceField(env, java_lang_ref_FinalizerReference, "zombie", "Ljava/lang/Object;"); if (!java_lang_ref_FinalizerReference_zombie) return FALSE; java_lang_ref_ReferenceQueue = rvmFindClassUsingLoader(env, "java/lang/ref/ReferenceQueue", NULL); if (!java_lang_ref_ReferenceQueue) return FALSE; java_lang_ref_ReferenceQueue_add = rvmGetClassMethod(env, java_lang_ref_ReferenceQueue, "add", "(Ljava/lang/ref/Reference;)V"); if (!java_lang_ref_ReferenceQueue_add) return FALSE; java_nio_ReadWriteDirectByteBuffer = rvmFindClassUsingLoader(env, "java/nio/ReadWriteDirectByteBuffer", NULL); if (!java_nio_ReadWriteDirectByteBuffer) return FALSE; java_nio_ReadWriteDirectByteBuffer_init = rvmGetInstanceMethod(env, java_nio_ReadWriteDirectByteBuffer, "<init>", "(II)V"); if (!java_nio_ReadWriteDirectByteBuffer_init) return FALSE; Class* java_nio_Buffer = rvmFindClassUsingLoader(env, "java/nio/Buffer", NULL); if (!java_nio_Buffer) return FALSE; java_nio_Buffer_effectiveDirectAddress = rvmGetInstanceField(env, java_nio_Buffer, "effectiveDirectAddress", "I"); if (!java_nio_Buffer_effectiveDirectAddress) return FALSE; java_nio_Buffer_capacity = rvmGetInstanceField(env, java_nio_Buffer, "capacity", "I"); if (!java_nio_Buffer_capacity) return FALSE; java_lang_Throwable_stackState = rvmGetInstanceField(env, java_lang_Throwable, "stackState", "J"); if (!java_lang_Throwable_stackState) return FALSE; org_robovm_rt_bro_Struct = rvmFindClassUsingLoader(env, "org/robovm/rt/bro/Struct", NULL); if (!org_robovm_rt_bro_Struct) { // We don't need Struct if it hasn't been compiled in rvmExceptionClear(env); } else { org_robovm_rt_bro_Struct_handle = rvmGetInstanceField(env, org_robovm_rt_bro_Struct, "handle", "J"); if (!org_robovm_rt_bro_Struct_handle) return FALSE; } java_nio_MemoryBlock = rvmFindClassUsingLoader(env, "java/nio/MemoryBlock", NULL); if (!java_nio_MemoryBlock) return FALSE; java_nio_MemoryBlock_address = rvmGetInstanceField(env, java_nio_MemoryBlock, "address", "I"); if (!java_nio_MemoryBlock_address) return FALSE; criticalOutOfMemoryError = rvmAllocateMemoryForObject(env, java_lang_OutOfMemoryError); if (!criticalOutOfMemoryError) return FALSE; criticalOutOfMemoryError->clazz = java_lang_OutOfMemoryError; if (!rvmAddObjectGCRoot(env, criticalOutOfMemoryError)) return FALSE; return TRUE; }