Example #1
0
extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
    LOCK_REGION(self->lock.asWrite());

    assert(self->cls == list_cls);
    assert(slice->cls == slice_cls);
    i64 start, stop, step;
    parseSlice(slice, self->size, &start, &stop, &step);
    RELEASE_ASSERT(step == 1, "step sizes must be 1 for now");

    assert(0 <= start && start < self->size);
    ASSERT(0 <= stop && stop <= self->size, "%ld %ld", self->size, stop);
    assert(start <= stop);

    ASSERT(v->cls == list_cls, "unsupported %s", getTypeName(v)->c_str());
    BoxedList* lv = static_cast<BoxedList*>(v);

    int delts = lv->size - (stop - start);
    int remaining_elts = self->size - stop;
    self->ensure(delts);

    memmove(self->elts->elts + start + lv->size, self->elts->elts + stop, remaining_elts * sizeof(Box*));
    for (int i = 0; i < lv->size; i++) {
        Box* r = lv->elts->elts[i];
        self->elts->elts[start + i] = r;
    }

    self->size += delts;

    return None;
}
Example #2
0
void* compilePartialFunc(OSRExit* exit) {
    LOCK_REGION(codegen_rwlock.asWrite());

    assert(exit);
    assert(exit->parent_cf);
    assert(exit->parent_cf->effort < EffortLevel::MAXIMAL);
    stat_osrexits.log();

    // if (VERBOSITY("irgen") >= 1) printf("In compilePartialFunc, handling %p\n", exit);

    assert(exit->parent_cf->clfunc);
    CompiledFunction*& new_cf = exit->parent_cf->clfunc->osr_versions[exit->entry];
    if (new_cf == NULL) {
        EffortLevel::EffortLevel new_effort = EffortLevel::MAXIMAL;
        if (exit->parent_cf->effort == EffortLevel::INTERPRETED)
            new_effort = EffortLevel::MINIMAL;
        // EffortLevel::EffortLevel new_effort = (EffortLevel::EffortLevel)(exit->parent_cf->effort + 1);
        // new_effort = EffortLevel::MAXIMAL;
        CompiledFunction* compiled
            = compileFunction(exit->parent_cf->clfunc, exit->parent_cf->spec, new_effort, exit->entry);
        assert(compiled = new_cf);
    }

    return new_cf->code;
}
Example #3
0
extern "C" Box* listInsert(BoxedList* self, Box* idx, Box* v) {
    if (idx->cls != int_cls) {
        raiseExcHelper(TypeError, "an integer is required");
    }

    LOCK_REGION(self->lock.asWrite());

    int64_t n = static_cast<BoxedInt*>(idx)->n;
    if (n < 0)
        n = self->size + n;

    if (n >= self->size) {
        listAppendInternal(self, v);
    } else {
        if (n < 0)
            n = 0;
        assert(0 <= n && n < self->size);

        self->ensure(1);
        memmove(self->elts->elts + n + 1, self->elts->elts + n, (self->size - n) * sizeof(Box*));

        self->size++;
        self->elts->elts[n] = v;
    }

    return None;
}
Example #4
0
void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
    CompiledFunction* cf;

    { // scope for limiting the locked region:
        LOCK_REGION(codegen_rwlock.asWrite());

        Timer _t("for compileModule()");

        bm->future_flags = getFutureFlags(m, bm->fn.c_str());

        ScopingAnalysis* scoping = runScopingAnalysis(m);

        SourceInfo* si = new SourceInfo(bm, scoping, m, m->body);
        si->cfg = computeCFG(si, m->body);
        si->liveness = computeLivenessInfo(si->cfg);
        si->phis = computeRequiredPhis(si->arg_names, si->cfg, si->liveness, si->getScopeInfo());

        CLFunction* cl_f = new CLFunction(0, 0, false, false, si);

        EffortLevel::EffortLevel effort = initialEffort();

        cf = compileFunction(cl_f, new FunctionSpecialization(VOID), effort, NULL);
        assert(cf->clfunc->versions.size());
    }

    if (cf->is_interpreted)
        interpretFunction(cf->func, 0, NULL, NULL, NULL, NULL, NULL, NULL);
    else
        ((void (*)())cf->code)();
}
Example #5
0
extern "C" Box* listPop(BoxedList* self, Box* idx) {
    LOCK_REGION(self->lock.asWrite());

    if (idx == None) {
        if (self->size == 0) {
            raiseExcHelper(IndexError, "pop from empty list");
        }

        self->size--;
        Box* rtn = self->elts->elts[self->size];
        return rtn;
    }

    if (idx->cls != int_cls) {
        raiseExcHelper(TypeError, "an integer is required");
    }

    int64_t n = static_cast<BoxedInt*>(idx)->n;
    if (n < 0)
        n = self->size + n;

    if (n < 0 || n >= self->size) {
        if (self->size == 0)
            fprintf(stderr, "IndexError: pop from empty list\n");
        else
            fprintf(stderr, "IndexError: pop index out of range\n");
        raiseExcHelper(IndexError, "");
    }

    Box* rtn = self->elts->elts[n];
    memmove(self->elts->elts + n, self->elts->elts + n + 1, (self->size - n - 1) * sizeof(Box*));
    self->size--;

    return rtn;
}
Example #6
0
Box* listSort1(BoxedList* self) {
    LOCK_REGION(self->lock.asWrite());

    assert(self->cls == list_cls);

    std::sort<Box**, PyLt>(self->elts->elts, self->elts->elts + self->size, PyLt());

    return None;
}
Example #7
0
extern "C" Box* listGetitemSlice(BoxedList* self, BoxedSlice* slice) {
    LOCK_REGION(self->lock.asRead());

    assert(self->cls == list_cls);
    assert(slice->cls == slice_cls);
    i64 start, stop, step, length;
    parseSlice(slice, self->size, &start, &stop, &step, &length);
    return _listSlice(self, start, stop, step, length);
}
Example #8
0
Box* listNe(BoxedList* self, Box* rhs) {
    if (rhs->cls != list_cls) {
        return NotImplemented;
    }

    LOCK_REGION(self->lock.asRead());

    return _listCmp(self, static_cast<BoxedList*>(rhs), AST_TYPE::NotEq);
}
Example #9
0
Box* listReverse(BoxedList* self) {
    LOCK_REGION(self->lock.asWrite());

    assert(self->cls == list_cls);
    for (int i = 0, j = self->size - 1; i < j; i++, j--) {
        Box* e = self->elts->elts[i];
        self->elts->elts[i] = self->elts->elts[j];
        self->elts->elts[j] = e;
    }

    return None;
}
Example #10
0
extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
    LOCK_REGION(self->lock.asWrite());

    assert(self->cls == list_cls);
    assert(slice->cls == slice_cls);

    i64 start = 0, stop = self->size, step = 1;

    sliceIndex(slice->start, &start);
    sliceIndex(slice->stop, &stop);
    sliceIndex(slice->step, &step);

    RELEASE_ASSERT(step == 1, "step sizes must be 1 for now");

    // Logic from PySequence_GetSlice:
    if (start < 0)
        start += self->size;
    if (stop < 0)
        stop += self->size;

    // Logic from list_ass_slice:
    if (start < 0)
        start = 0;
    else if (start > self->size)
        start = self->size;

    if (stop < start)
        stop = start;
    else if (stop > self->size)
        stop = self->size;

    assert(0 <= start && start <= stop && stop <= self->size);

    RELEASE_ASSERT(v->cls == list_cls, "unsupported %s", getTypeName(v)->c_str());
    BoxedList* lv = static_cast<BoxedList*>(v);

    RELEASE_ASSERT(self->elts != lv->elts, "Slice self-assignment currently unsupported");

    int delts = lv->size - (stop - start);
    int remaining_elts = self->size - stop;
    self->ensure(delts);

    memmove(self->elts->elts + start + lv->size, self->elts->elts + stop, remaining_elts * sizeof(Box*));
    for (int i = 0; i < lv->size; i++) {
        Box* r = lv->elts->elts[i];
        self->elts->elts[start + i] = r;
    }

    self->size += delts;

    return None;
}
Example #11
0
extern "C" Box* listGetitemUnboxed(BoxedList* self, int64_t n) {
    LOCK_REGION(self->lock.asRead());

    assert(self->cls == list_cls);
    if (n < 0)
        n = self->size + n;

    if (n < 0 || n >= self->size) {
        raiseExcHelper(IndexError, "list index out of range");
    }
    Box* rtn = self->elts->elts[n];
    return rtn;
}
Example #12
0
Box* listContains(BoxedList* self, Box* elt) {
    LOCK_REGION(self->lock.asRead());

    int size = self->size;
    for (int i = 0; i < size; i++) {
        Box* e = self->elts->elts[i];
        Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
        bool b = nonzero(cmp);
        if (b)
            return True;
    }
    return False;
}
Example #13
0
extern "C" Box* listDelitemInt(BoxedList* self, BoxedInt* slice) {
    LOCK_REGION(self->lock.asWrite());

    int64_t n = slice->n;
    if (n < 0)
        n = self->size + n;

    if (n < 0 || n >= self->size) {
        raiseExcHelper(IndexError, "list index out of range");
    }
    memmove(self->elts->elts + n, self->elts->elts + n + 1, (self->size - n - 1) * sizeof(Box*));
    self->size--;
    return None;
}
Example #14
0
SmallArena::ThreadBlockCache::~ThreadBlockCache() {
    LOCK_REGION(heap->lock);

    for (int i = 0; i < NUM_BUCKETS; i++) {
        while (Block* b = cache_free_heads[i]) {
            removeFromLLAndNull(b);
            insertIntoLL(&small->heads[i], b);
        }

        while (Block* b = cache_full_heads[i]) {
            removeFromLLAndNull(b);
            insertIntoLL(&small->full_heads[i], b);
        }
    }
}
Example #15
0
extern "C" Box* listDelitem(BoxedList* self, Box* slice) {
    LOCK_REGION(self->lock.asWrite());

    Box* rtn;

    if (isSubclass(slice->cls, int_cls)) {
        rtn = listDelitemInt(self, static_cast<BoxedInt*>(slice));
    } else if (slice->cls == slice_cls) {
        rtn = listDelitemSlice(self, static_cast<BoxedSlice*>(slice));
    } else {
        raiseExcHelper(TypeError, "list indices must be integers, not %s", getTypeName(slice)->c_str());
    }
    self->shrink();
    return rtn;
}
Example #16
0
Box* listCount(BoxedList* self, Box* elt) {
    LOCK_REGION(self->lock.asRead());

    int size = self->size;
    int count = 0;

    for (int i = 0; i < size; i++) {
        Box* e = self->elts->elts[i];
        Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
        bool b = nonzero(cmp);
        if (b)
            count++;
    }
    return boxInt(count);
}
Example #17
0
GCAllocation* LargeArena::alloc(size_t size) {
    registerGCManagedBytes(size);

    LOCK_REGION(heap->lock);

    // printf ("allocLarge %zu\n", size);

    LargeObj* obj = _alloc(size + sizeof(GCAllocation) + sizeof(LargeObj));

    obj->size = size;

    nullNextPrev(obj);
    insertIntoLL(&head, obj);

    return obj->data;
}
Example #18
0
Box* listIndex(BoxedList* self, Box* elt) {
    LOCK_REGION(self->lock.asRead());

    int size = self->size;

    for (int i = 0; i < size; i++) {
        Box* e = self->elts->elts[i];
        Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
        bool b = nonzero(cmp);
        if (b)
            return boxInt(i);
    }

    BoxedString* tostr = static_cast<BoxedString*>(repr(elt));
    raiseExcHelper(ValueError, "%s is not in list", tostr->s.c_str());
}
Example #19
0
extern "C" Box* listRepr(BoxedList* self) {
    LOCK_REGION(self->lock.asRead());

    // TODO highly inefficient with all the string copying
    std::ostringstream os;
    os << '[';
    for (int i = 0; i < self->size; i++) {
        if (i > 0)
            os << ", ";

        BoxedString* s = static_cast<BoxedString*>(self->elts->elts[i]->reprIC());
        os << s->s;
    }
    os << ']';
    return new BoxedString(os.str());
}
Example #20
0
extern "C" Box* listSetitemInt(BoxedList* self, BoxedInt* slice, Box* v) {
    // I think r lock is ok here, since we don't change the list structure:
    LOCK_REGION(self->lock.asRead());

    assert(self->cls == list_cls);
    assert(isSubclass(slice->cls, int_cls));
    int64_t n = slice->n;
    if (n < 0)
        n = self->size + n;

    if (n < 0 || n >= self->size) {
        raiseExcHelper(IndexError, "list index out of range");
    }

    self->elts->elts[n] = v;
    return None;
}
Example #21
0
Box* listIAdd(BoxedList* self, Box* _rhs) {
    if (_rhs->cls != list_cls) {
        raiseExcHelper(TypeError, "can only concatenate list (not \"%s\") to list", getTypeName(_rhs)->c_str());
    }

    LOCK_REGION(self->lock.asWrite());

    BoxedList* rhs = static_cast<BoxedList*>(_rhs);

    int s1 = self->size;
    int s2 = rhs->size;
    self->ensure(s1 + s2);

    memcpy(self->elts->elts + s1, rhs->elts->elts, sizeof(rhs->elts->elts[0]) * s2);
    self->size = s1 + s2;
    return self;
}
Example #22
0
extern "C" Box* listDelitemSlice(BoxedList* self, BoxedSlice* slice) {
    LOCK_REGION(self->lock.asWrite());

    i64 start, stop, step;
    parseSlice(slice, self->size, &start, &stop, &step);
    RELEASE_ASSERT(step == 1, "step sizes must be 1 for now");

    assert(0 <= start && start < self->size);
    ASSERT(0 <= stop && stop <= self->size, "%ld %ld", self->size, stop);
    assert(start <= stop);

    int remaining_elts = self->size - stop;

    memmove(self->elts->elts + start, self->elts->elts + stop, remaining_elts * sizeof(Box*));
    self->size -= (stop - start);
    return None;
}
Example #23
0
GCAllocation* SmallArena::_alloc(size_t rounded_size, int bucket_idx) {
    Block** free_head = &heads[bucket_idx];
    Block** full_head = &full_heads[bucket_idx];

    static __thread ThreadBlockCache* cache = NULL;
    if (!cache)
        cache = thread_caches.get();

    Block** cache_head = &cache->cache_free_heads[bucket_idx];

    // static __thread int gc_allocs = 0;
    // if (++gc_allocs == 128) {
    // static StatCounter sc_total("gc_allocs");
    // sc_total.log(128);
    // gc_allocs = 0;
    //}

    while (true) {
        while (Block* cache_block = *cache_head) {
            GCAllocation* rtn = _allocFromBlock(cache_block);
            if (rtn)
                return rtn;

            removeFromLLAndNull(cache_block);
            insertIntoLL(&cache->cache_full_heads[bucket_idx], cache_block);
        }

        // Not very useful to count the cache misses if we don't count the total attempts:
        // static StatCounter sc_fallback("gc_allocs_cachemiss");
        // sc_fallback.log();

        LOCK_REGION(heap->lock);

        assert(*cache_head == NULL);

        // should probably be called allocBlock:
        Block* myblock = _claimBlock(rounded_size, &heads[bucket_idx]);
        assert(myblock);
        assert(!myblock->next);
        assert(!myblock->prev);

        // printf("%d claimed new block %p with %d objects\n", threading::gettid(), myblock, myblock->numObjects());

        insertIntoLL(cache_head, myblock);
    }
}
Example #24
0
Box* listRemove(BoxedList* self, Box* elt) {
    LOCK_REGION(self->lock.asWrite());

    assert(self->cls == list_cls);

    for (int i = 0; i < self->size; i++) {
        Box* e = self->elts->elts[i];
        Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
        bool b = nonzero(cmp);

        if (b) {
            memmove(self->elts->elts + i, self->elts->elts + i + 1, (self->size - i - 1) * sizeof(Box*));
            self->size--;
            return None;
        }
    }

    raiseExcHelper(ValueError, "list.remove(x): x not in list");
}
Example #25
0
Box* listIAdd(BoxedList* self, Box* _rhs) {
    LOCK_REGION(self->lock.asWrite());

    if (_rhs->cls == list_cls) {
        // This branch is safe if self==rhs:
        BoxedList* rhs = static_cast<BoxedList*>(_rhs);

        int s1 = self->size;
        int s2 = rhs->size;
        self->ensure(s1 + s2);

        memcpy(self->elts->elts + s1, rhs->elts->elts, sizeof(rhs->elts->elts[0]) * s2);
        self->size = s1 + s2;
        return self;
    }

    RELEASE_ASSERT(_rhs != self, "unsupported");

    for (auto* b : _rhs->pyElements())
        listAppendInternal(self, b);

    return self;
}
Example #26
0
/// Reoptimizes the given function version at the new effort level.
/// The cf must be an active version in its parents CLFunction; the given
/// version will be replaced by the new version, which will be returned.
static CompiledFunction* _doReopt(CompiledFunction* cf, EffortLevel::EffortLevel new_effort) {
    LOCK_REGION(codegen_rwlock.asWrite());

    assert(cf->clfunc->versions.size());

    assert(cf);
    assert(cf->entry_descriptor == NULL && "We can't reopt an osr-entry compile!");
    assert(cf->spec);

    CLFunction* clfunc = cf->clfunc;
    assert(clfunc);

    assert(new_effort > cf->effort);

    FunctionList& versions = clfunc->versions;
    for (int i = 0; i < versions.size(); i++) {
        if (versions[i] == cf) {
            versions.erase(versions.begin() + i);

            CompiledFunction* new_cf
                = compileFunction(clfunc, cf->spec, new_effort,
                                  NULL); // this pushes the new CompiledVersion to the back of the version list

            cf->dependent_callsites.invalidateAll();

            return new_cf;
        }
    }

    printf("Couldn't find a version; %ld exist:\n", versions.size());
    for (auto cf : versions) {
        printf("%p\n", cf);
    }
    assert(0 && "Couldn't find a version to reopt! Probably reopt'd already?");
    abort();
}
Example #27
0
Box* listMul(BoxedList* self, Box* rhs) {
    if (rhs->cls != int_cls) {
        raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs)->c_str());
    }

    LOCK_REGION(self->lock.asRead());

    int n = static_cast<BoxedInt*>(rhs)->n;
    int s = self->size;

    BoxedList* rtn = new BoxedList();
    rtn->ensure(n * s);
    if (s == 1) {
        for (int i = 0; i < n; i++) {
            listAppendInternal(rtn, self->elts->elts[0]);
        }
    } else {
        for (int i = 0; i < n; i++) {
            listAppendArrayInternal(rtn, &self->elts->elts[0], s);
        }
    }

    return rtn;
}