void PriorityQueueAdd(struct VMGlobals *g, PyrObject* queueobj, PyrSlot* item, double time) { PyrObject *schedq, *newschedq; int size, maxsize; PyrSlot *schedqSlot = queueobj->slots; if (!IsObj(schedqSlot)) { size = 32; schedq = newPyrArray(g->gc, size, 0, true); schedq->size = 1; SetInt(schedq->slots + 0, 0); // stability count SetObject(schedqSlot, schedq); g->gc->GCWriteNew(queueobj, schedq); // we know schedq is white so we can use GCWriteNew } else { schedq = slotRawObject(schedqSlot); maxsize = ARRAYMAXINDEXSIZE(schedq); size = schedq->size; if (size+3 > maxsize) { newschedq = newPyrArray(g->gc, maxsize*2, 0, true); newschedq->size = size; slotCopy(newschedq->slots, schedq->slots, size); assert(IsInt(newschedq->slots)); SetObject(schedqSlot, newschedq); g->gc->GCWriteNew(queueobj, newschedq); // we know newschedq is white so we can use GCWriteNew schedq = newschedq; } } addheap(g, schedq, time, item); }
void PriorityQueueAdd(struct VMGlobals *g, PyrObject* queueobj, PyrSlot* item, double time) { PyrObject *schedq, *newschedq; int size, maxsize; PyrSlot *schedqSlot = queueobj->slots; if (!IsObj(schedqSlot)) { size = 16; schedq = newPyrArray(g->gc, size, 0, true); SetObject(schedqSlot, schedq); g->gc->GCWrite(queueobj, schedq); } else { schedq = schedqSlot->uo; maxsize = ARRAYMAXINDEXSIZE(schedq); size = schedq->size; if (size+2 > maxsize) { PyrSlot *pslot, *qslot; newschedq = newPyrArray(g->gc, maxsize*2, 0, true); newschedq->size = size; pslot = schedq->slots - 1; qslot = newschedq->slots - 1; for (int i=0; i<size; ++i) slotCopy(++qslot, ++pslot); SetObject(schedqSlot, newschedq); g->gc->GCWrite(queueobj, newschedq); schedq = newschedq; } } addheap(g, schedq, time, item); }
int prIdentDict_PutGet(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, *b, *c, *d, *slot, *newslot; int i, index, size; PyrObject *dict; PyrObject *array; a = g->sp - 2; // dict b = g->sp - 1; // key c = g->sp; // value d = ++g->sp; // push the stack to save the receiver slotCopy(d,a); dict = slotRawObject(d); array = slotRawObject(&dict->slots[ivxIdentDict_array]); if (!isKindOf((PyrObject*)array, class_array)) { SetNil(a); --g->sp; return errFailed; } index = arrayAtIdentityHashInPairs(array, b); slot = array->slots + index; slotCopy(a,&slot[1]); slotCopy(&slot[1],c); g->gc->GCWrite(array, c); if (IsNil(slot)) { slotCopy(slot,b); g->gc->GCWrite(array, b); size = slotRawInt(&dict->slots[ivxIdentDict_size]) + 1; SetRaw(&dict->slots[ivxIdentDict_size], size); if (array->size < size*3) { PyrObject *newarray; newarray = newPyrArray(g->gc, size*3, 0, true); newarray->size = ARRAYMAXINDEXSIZE(newarray); nilSlots(newarray->slots, newarray->size); slot = array->slots; for (i=0; i<array->size; i+=2, slot+=2) { if (NotNil(slot)) { index = arrayAtIdentityHashInPairs(newarray, slot); newslot = newarray->slots + index; slotCopy(&newslot[0],&slot[0]); slotCopy(&newslot[1],&slot[1]); } } SetRaw(&dict->slots[ivxIdentDict_array], newarray); g->gc->GCWriteNew(dict, newarray); // we know newarray is white so we can use GCWriteNew } } --g->sp; return errNone; }
int identDictPut(struct VMGlobals *g, PyrObject *dict, PyrSlot *key, PyrSlot *value) { PyrSlot *slot, *newslot; int i, index, size; PyrObject *array; bool knows = IsTrue(dict->slots + ivxIdentDict_know); if (knows && IsSym(key)) { if (slotRawSymbol(key) == s_parent) { slotCopy(&dict->slots[ivxIdentDict_parent],value); g->gc->GCWrite(dict, value); return errNone; } if (slotRawSymbol(key) == s_proto) { slotCopy(&dict->slots[ivxIdentDict_proto],value); g->gc->GCWrite(dict, value); return errNone; } } array = slotRawObject(&dict->slots[ivxIdentDict_array]); if (array->IsImmutable()) return errImmutableObject; if (!isKindOf((PyrObject*)array, class_array)) return errFailed; index = arrayAtIdentityHashInPairs(array, key); slot = array->slots + index; slotCopy(&slot[1],value); g->gc->GCWrite(array, value); if (IsNil(slot)) { slotCopy(slot,key); g->gc->GCWrite(array, key); size = slotRawInt(&dict->slots[ivxIdentDict_size]) + 1; SetRaw(&dict->slots[ivxIdentDict_size], size); if (array->size < size*3) { PyrObject *newarray; newarray = newPyrArray(g->gc, size*3, 0, false); newarray->size = ARRAYMAXINDEXSIZE(newarray); nilSlots(newarray->slots, newarray->size); slot = array->slots; for (i=0; i<array->size; i+=2, slot+=2) { if (NotNil(slot)) { index = arrayAtIdentityHashInPairs(newarray, slot); newslot = newarray->slots + index; slotCopy(&newslot[0],&slot[0]); slotCopy(&newslot[1],&slot[1]); } } SetRaw(&dict->slots[ivxIdentDict_array], newarray); g->gc->GCWriteNew(dict, newarray); // we know newarray is white so we can use GCWriteNew } } return errNone; }
int identDictPut(struct VMGlobals *g, PyrObject *dict, PyrSlot *key, PyrSlot *value) { PyrSlot *slot, *newslot; int i, index, size; PyrObject *array; bool knows = IsTrue(dict->slots + ivxIdentDict_know); if (knows && IsSym(key)) { if (key->us == s_parent) { slotCopy(&dict->slots[ivxIdentDict_parent],value); g->gc->GCWrite(dict, value); return errNone; } if (key->us == s_proto) { slotCopy(&dict->slots[ivxIdentDict_proto],value); g->gc->GCWrite(dict, value); return errNone; } } array = dict->slots[ivxIdentDict_array].uo; if (!isKindOf((PyrObject*)array, class_array)) return errFailed; index = arrayAtIdentityHashInPairs(array, key); slot = array->slots + index; slotCopy(&slot[1],value); g->gc->GCWrite(array, value); if (IsNil(slot)) { slotCopy(slot,key); g->gc->GCWrite(array, key); size = ++dict->slots[ivxIdentDict_size].ui; if (array->size < size*3) { PyrObject *newarray; newarray = newPyrArray(g->gc, size*3, 0, false); newarray->size = ARRAYMAXINDEXSIZE(newarray); nilSlots(newarray->slots, newarray->size); slot = array->slots; for (i=0; i<array->size; i+=2, slot+=2) { if (NotNil(slot)) { index = arrayAtIdentityHashInPairs(newarray, slot); newslot = newarray->slots + index; slotCopy(&newslot[0],&slot[0]); slotCopy(&newslot[1],&slot[1]); } } dict->slots[ivxIdentDict_array].uo = newarray; g->gc->GCWrite(dict, newarray); } } return errNone; }
bool addheap(VMGlobals *g, PyrObject *heapArg, double schedtime, PyrSlot *task) { PyrHeap * heap = (PyrHeap*)heapArg; #ifdef GC_SANITYCHECK g->gc->SanityCheck(); #endif if (heap->size >= ARRAYMAXINDEXSIZE(heap)) return false; assert(heap->size); // post("->addheap\n"); // dumpheap(heapArg); /* parent and sibling in the heap, not in the task hierarchy */ int mom = heap->size - 1; PyrSlot * pme = heap->slots + mom; int stabilityCount = slotRawInt(&heap->count); SetRaw(&heap->count, stabilityCount + 1); for (; mom>0;) { /* percolate up heap */ int newMom = ((mom - 3) / 2); mom = newMom - newMom % 3; /// LATER: we could avoid the division by using 4 slots per element PyrSlot * pmom = heap->slots + mom; if (schedtime < slotRawFloat(pmom)) { assert(slotRawInt(pmom + 2) < stabilityCount); slotCopy(&pme[0], &pmom[0]); slotCopy(&pme[1], &pmom[1]); slotCopy(&pme[2], &pmom[2]); pme = pmom; } else break; } SetFloat(&pme[0], schedtime); slotCopy(&pme[1], task); SetInt(&pme[2], stabilityCount); g->gc->GCWrite(heap, task); heap->size += 3; #ifdef GC_SANITYCHECK g->gc->SanityCheck(); #endif // dumpheap(heapArg); // post("<-addheap %g\n", schedtime); return true; }