Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions from_cpython/Modules/_sre.c
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,9 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
if (!ptr)
return NULL;

// Pyston change:
assert(charsize == 1 || charsize == sizeof(Py_UNICODE));

/* adjust boundaries */
if (start < 0)
start = 0;
Expand Down Expand Up @@ -1813,8 +1816,15 @@ state_fini(SRE_STATE* state)
}

/* calculate offset from start of string */
// Pyston change: this division is expensive
/*
#define STATE_OFFSET(state, member)\
(((char*)(member) - (char*)(state)->beginning) / (state)->charsize)
*/
#define STATE_OFFSET(state, member) \
((state)->charsize == 1 ? \
(((char*)(member) - (char*)(state)->beginning)) : \
(((char*)(member) - (char*)(state)->beginning) / sizeof(Py_UNICODE)))

LOCAL(PyObject*)
state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty)
Expand Down
55 changes: 48 additions & 7 deletions src/capi/abstract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1441,14 +1441,55 @@ extern "C" PyObject* PySequence_GetItem(PyObject* o, Py_ssize_t i) noexcept {
}
}

extern "C" PyObject* PySequence_GetSlice(PyObject* o, Py_ssize_t i1, Py_ssize_t i2) noexcept {
try {
// Not sure if this is really the same:
return getitem(o, createSlice(boxInt(i1), boxInt(i2), None));
} catch (ExcInfo e) {
fatalOrError(PyExc_NotImplementedError, "unimplemented");
return nullptr;
PyObject* _PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop) {
PyObject* start, *end, *slice;
start = PyInt_FromSsize_t(istart);
if (!start)
return NULL;
end = PyInt_FromSsize_t(istop);
if (!end) {
Py_DECREF(start);
return NULL;
}

slice = PySlice_New(start, end, NULL);
Py_DECREF(start);
Py_DECREF(end);
return slice;
}

extern "C" PyObject* PySequence_GetSlice(PyObject* s, Py_ssize_t i1, Py_ssize_t i2) noexcept {
PySequenceMethods* m;
PyMappingMethods* mp;

if (!s)
return null_error();

m = s->cls->tp_as_sequence;
if (m && m->sq_slice) {
if (i1 < 0 || i2 < 0) {
if (m->sq_length) {
Py_ssize_t l = (*m->sq_length)(s);
if (l < 0)
return NULL;
if (i1 < 0)
i1 += l;
if (i2 < 0)
i2 += l;
}
}
return m->sq_slice(s, i1, i2);
} else if ((mp = s->cls->tp_as_mapping) && mp->mp_subscript) {
PyObject* res;
PyObject* slice = _PySlice_FromIndices(i1, i2);
if (!slice)
return NULL;
res = mp->mp_subscript(s, slice);
Py_DECREF(slice);
return res;
}

return type_error("'%.200s' object is unsliceable", s);
}

extern "C" int PySequence_SetItem(PyObject* o, Py_ssize_t i, PyObject* v) noexcept {
Expand Down
2 changes: 2 additions & 0 deletions src/capi/typeobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1112,12 +1112,14 @@ static int slot_sq_ass_slice(PyObject* self, Py_ssize_t i, Py_ssize_t j, PyObjec
// Copied from CPython:
#define SLOT0(FUNCNAME, OPSTR) \
static PyObject* FUNCNAME(PyObject* self) noexcept { \
STAT_TIMER(t0, "us_timer_" #FUNCNAME, SLOT_AVOIDABILITY(self)); \
static PyObject* cache_str; \
return call_method(self, OPSTR, &cache_str, "()"); \
}

#define SLOT1(FUNCNAME, OPSTR, ARG1TYPE, ARGCODES) \
/* Pyston change: static */ PyObject* FUNCNAME(PyObject* self, ARG1TYPE arg1) noexcept { \
STAT_TIMER(t0, "us_timer_" #FUNCNAME, SLOT_AVOIDABILITY(self)); \
static PyObject* cache_str; \
return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \
}
Expand Down
1 change: 1 addition & 0 deletions src/codegen/ast_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "runtime/generator.h"
#include "runtime/import.h"
#include "runtime/inline/boxing.h"
#include "runtime/inline/list.h"
#include "runtime/long.h"
#include "runtime/objmodel.h"
#include "runtime/set.h"
Expand Down
1 change: 1 addition & 0 deletions src/codegen/baseline_jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "codegen/memmgr.h"
#include "codegen/type_recording.h"
#include "core/cfg.h"
#include "runtime/inline/list.h"
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
Expand Down
1 change: 1 addition & 0 deletions src/codegen/runtime_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "runtime/generator.h"
#include "runtime/import.h"
#include "runtime/inline/boxing.h"
#include "runtime/inline/list.h"
#include "runtime/int.h"
#include "runtime/long.h"
#include "runtime/objmodel.h"
Expand Down
4 changes: 2 additions & 2 deletions src/gc/heap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ GCAllocation* LargeArena::allocationFrom(void* ptr) {

void LargeArena::prepareForCollection() {
for (LargeObj* lo = head; lo; lo = lo->next) {
lookup.push_back(ObjLookupCache(lo, &lo->data[0], lo->size));
lookup.push_back(ObjLookupCache(&lo->data[0], lo->size));
}
std::sort(lookup.begin(), lookup.end(),
[](const ObjLookupCache& lo1, const ObjLookupCache& lo2) { return lo1.data < lo2.data; });
Expand Down Expand Up @@ -904,7 +904,7 @@ GCAllocation* HugeArena::allocationFrom(void* ptr) {

void HugeArena::prepareForCollection() {
for (HugeObj* lo = head; lo; lo = lo->next) {
lookup.push_back(ObjLookupCache(lo, &lo->data[0], lo->size));
lookup.push_back(ObjLookupCache(&lo->data[0], lo->size));
}
std::sort(lookup.begin(), lookup.end(),
[](const ObjLookupCache& lo1, const ObjLookupCache& lo2) { return lo1.data < lo2.data; });
Expand Down
3 changes: 1 addition & 2 deletions src/gc/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,10 @@ class SmallArena : public Arena<SMALL_ARENA_START, ARENA_SIZE, 64 * 1024 * 1024,
};

struct ObjLookupCache {
void* objptr;
void* data;
size_t size;

ObjLookupCache(void* objptr, void* data, size_t size) : objptr(objptr), data(data), size(size) {}
ObjLookupCache(void* data, size_t size) : data(data), size(size) {}
};


Expand Down
1 change: 1 addition & 0 deletions src/runtime/builtin_modules/builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "runtime/file.h"
#include "runtime/ics.h"
#include "runtime/import.h"
#include "runtime/inline/list.h"
#include "runtime/inline/xrange.h"
#include "runtime/iterobject.h"
#include "runtime/list.h"
Expand Down
1 change: 1 addition & 0 deletions src/runtime/builtin_modules/sys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "gc/collector.h"
#include "runtime/file.h"
#include "runtime/inline/boxing.h"
#include "runtime/inline/list.h"
#include "runtime/int.h"
#include "runtime/types.h"
#include "runtime/util.h"
Expand Down
1 change: 1 addition & 0 deletions src/runtime/dict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "core/stats.h"
#include "core/types.h"
#include "gc/collector.h"
#include "runtime/inline/list.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/util.h"
Expand Down
1 change: 1 addition & 0 deletions src/runtime/import.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "codegen/parser.h"
#include "codegen/unwinding.h"
#include "core/ast.h"
#include "runtime/inline/list.h"
#include "runtime/objmodel.h"

namespace pyston {
Expand Down
1 change: 1 addition & 0 deletions src/runtime/inline/link_forcer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "runtime/generator.h"
#include "runtime/import.h"
#include "runtime/inline/boxing.h"
#include "runtime/inline/list.h"
#include "runtime/int.h"
#include "runtime/list.h"
#include "runtime/long.h"
Expand Down
34 changes: 2 additions & 32 deletions src/runtime/inline/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "runtime/inline/list.h"

#include <cstring>

#include "runtime/list.h"
Expand Down Expand Up @@ -111,38 +113,6 @@ void BoxedList::shrink() {
}
}

// TODO the inliner doesn't want to inline these; is there any point to having them in the inline section?
void BoxedList::ensure(int space) {
if (size + space > capacity) {
if (capacity == 0) {
const int INITIAL_CAPACITY = 8;
int initial = std::max(INITIAL_CAPACITY, space);
elts = new (initial) GCdArray();
capacity = initial;
} else {
int new_capacity = std::max(capacity * 2, size + space);
elts = GCdArray::realloc(elts, new_capacity);
capacity = new_capacity;
}
}
assert(capacity >= size + space);
}

// TODO the inliner doesn't want to inline these; is there any point to having them in the inline section?
extern "C" void listAppendInternal(Box* s, Box* v) {
// Lock must be held!

assert(isSubclass(s->cls, list_cls));
BoxedList* self = static_cast<BoxedList*>(s);

assert(self->size <= self->capacity);
self->ensure(1);

assert(self->size < self->capacity);
self->elts->elts[self->size] = v;
self->size++;
}


extern "C" void listAppendArrayInternal(Box* s, Box** v, int nelts) {
// Lock must be held!
Expand Down
60 changes: 60 additions & 0 deletions src/runtime/inline/list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef PYSTON_RUNTIME_INLINE_LIST_H
#define PYSTON_RUNTIME_INLINE_LIST_H

#include "runtime/list.h"
#include "runtime/objmodel.h"

namespace pyston {

// TODO the inliner doesn't want to inline these; is there any point to having them in the inline section?
inline void BoxedList::grow(int min_free) {
if (capacity == 0) {
const int INITIAL_CAPACITY = 8;
int initial = std::max(INITIAL_CAPACITY, min_free);
elts = new (initial) GCdArray();
capacity = initial;
} else {
int new_capacity = std::max(capacity * 2, size + min_free);
elts = GCdArray::realloc(elts, new_capacity);
capacity = new_capacity;
}
}

inline void BoxedList::ensure(int min_free) {
if (unlikely(size + min_free > capacity)) {
grow(min_free);
}
assert(capacity >= size + min_free);
}

// TODO the inliner doesn't want to inline these; is there any point to having them in the inline section?
extern "C" inline void listAppendInternal(Box* s, Box* v) {
// Lock must be held!

assert(isSubclass(s->cls, list_cls));
BoxedList* self = static_cast<BoxedList*>(s);

assert(self->size <= self->capacity);
self->ensure(1);

assert(self->size < self->capacity);
self->elts->elts[self->size] = v;
self->size++;
}
}

#endif
43 changes: 42 additions & 1 deletion src/runtime/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@
#include "core/types.h"
#include "gc/collector.h"
#include "gc/roots.h"
#include "runtime/inline/list.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/util.h"

namespace pyston {

extern "C" int PyList_Append(PyObject* op, PyObject* newitem) noexcept {
RELEASE_ASSERT(PyList_Check(op), "");
try {
listAppend(op, newitem);
listAppendInternal(op, newitem);
} catch (ExcInfo e) {
abort();
}
Expand Down Expand Up @@ -131,6 +133,10 @@ extern "C" Box* listLen(BoxedList* self) {
return boxInt(self->size);
}

static Py_ssize_t list_length(Box* self) noexcept {
return static_cast<BoxedList*>(self)->size;
}

Box* _listSlice(BoxedList* self, i64 start, i64 stop, i64 step, i64 length) {
// printf("%ld %ld %ld\n", start, stop, step);
assert(step != 0);
Expand All @@ -151,6 +157,38 @@ Box* _listSlice(BoxedList* self, i64 start, i64 stop, i64 step, i64 length) {
return rtn;
}

static Box* list_slice(Box* o, Py_ssize_t ilow, Py_ssize_t ihigh) noexcept {
BoxedList* a = static_cast<BoxedList*>(o);

PyObject** src, **dest;
Py_ssize_t i, len;
if (ilow < 0)
ilow = 0;
else if (ilow > Py_SIZE(a))
ilow = Py_SIZE(a);
if (ihigh < ilow)
ihigh = ilow;
else if (ihigh > Py_SIZE(a))
ihigh = Py_SIZE(a);
len = ihigh - ilow;

BoxedList* np = new BoxedList();

np->ensure(len);
if (len) {
src = a->elts->elts + ilow;
dest = np->elts->elts;
for (i = 0; i < len; i++) {
PyObject* v = src[i];
Py_INCREF(v);
dest[i] = v;
}
}
np->size = len;

return (PyObject*)np;
}

extern "C" Box* listGetitemUnboxed(BoxedList* self, int64_t n) {
LOCK_REGION(self->lock.asRead());

Expand Down Expand Up @@ -1141,6 +1179,9 @@ void setupList() {
list_cls->giveAttr("__hash__", None);
list_cls->freeze();

list_cls->tp_as_sequence->sq_slice = list_slice;
list_cls->tp_as_sequence->sq_length = list_length;

CLFunction* hasnext = boxRTFunction((void*)listiterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)listiterHasnext, BOXED_BOOL);
list_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
Expand Down
Loading