Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
b322d2b2
Commit
b322d2b2
authored
Jun 30, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #658 from kmod/perf7
fastpath investigations
parents
96674bed
cab7c2dc
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
231 additions
and
135 deletions
+231
-135
CMakeLists.txt
CMakeLists.txt
+1
-1
Makefile
Makefile
+3
-1
from_cpython/Include/abstract.h
from_cpython/Include/abstract.h
+1
-1
from_cpython/Include/tupleobject.h
from_cpython/Include/tupleobject.h
+3
-16
src/asm_writing/rewriter.cpp
src/asm_writing/rewriter.cpp
+46
-0
src/codegen/parser.cpp
src/codegen/parser.cpp
+1
-9
src/core/stats.cpp
src/core/stats.cpp
+2
-0
src/gc/collector.cpp
src/gc/collector.cpp
+16
-4
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+2
-0
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+1
-1
src/runtime/classobj.cpp
src/runtime/classobj.cpp
+2
-0
src/runtime/code.cpp
src/runtime/code.cpp
+1
-1
src/runtime/descr.cpp
src/runtime/descr.cpp
+5
-1
src/runtime/list.cpp
src/runtime/list.cpp
+2
-2
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+26
-3
src/runtime/str.cpp
src/runtime/str.cpp
+60
-60
src/runtime/tuple.cpp
src/runtime/tuple.cpp
+0
-6
src/runtime/types.cpp
src/runtime/types.cpp
+7
-2
src/runtime/types.h
src/runtime/types.h
+52
-8
test/extra/pyicu_101.patch
test/extra/pyicu_101.patch
+0
-19
No files found.
CMakeLists.txt
View file @
b322d2b2
...
...
@@ -177,7 +177,7 @@ if(ENABLE_OPROFILE)
set
(
OPTIONAL_LIBRARIES
${
OPTIONAL_LIBRARIES
}
opagent
)
endif
()
set
(
CMAKE_C_FLAGS
"
${
CMAKE_C_FLAGS
}
-Wall -Wextra -Werror -Wreturn-type -Wno-sign-compare -Wno-unused -Wno-unused-parameter -fno-omit-frame-pointer"
)
set
(
CMAKE_C_FLAGS
"
${
CMAKE_C_FLAGS
}
-Wall -Wextra -Werror -Wreturn-type -Wno-sign-compare -Wno-unused -Wno-unused-parameter -fno-omit-frame-pointer
-g
"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
${
CMAKE_C_FLAGS
}
-std=c++11 -fno-rtti -fexceptions -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -Woverloaded-virtual -Wno-invalid-offsetof -Wcast-qual -Wno-sign-conversion -Wnon-virtual-dtor -Winit-self -Wmissing-include-dirs -Wstrict-overflow=5 -Wpointer-arith -Wtype-limits -Wwrite-strings -Wempty-body -Waggregate-return -Wmissing-field-initializers -Wredundant-decls -Winline -Wint-to-pointer-cast -Wlong-long -Wvla -Wno-attributes -g"
)
set
(
CLANG_FLAGS
"
${
CLANG_FLAGS
}
-Wimplicit-int -Wstrict-prototypes -Wold-style-definition -Wnested-externs -Wpointer-to-int-cast -Wno-mismatched-tags -Wno-extern-c-compat"
)
...
...
Makefile
View file @
b322d2b2
...
...
@@ -19,6 +19,8 @@ USE_CLANG := 1
USE_CCACHE
:=
1
USE_DISTCC
:=
0
PYPY
:=
pypy
ENABLE_VALGRIND
:=
0
GDB
:=
gdb
...
...
@@ -1024,7 +1026,7 @@ $(call make_target,_gcc)
nosearch_runpy_% nosearch_pyrun_%
:
%.py ext_python
$(VERB)
PYTHONPATH
=
test
/test_extension/build/lib.linux-x86_64-2.7 zsh
-c
'time python $<'
nosearch_pypyrun_%
:
%.py ext_python
$(VERB)
PYTHONPATH
=
test
/test_extension/build/lib.linux-x86_64-2.7 zsh
-c
'time
pypy
$<'
$(VERB)
PYTHONPATH
=
test
/test_extension/build/lib.linux-x86_64-2.7 zsh
-c
'time
$(PYPY)
$<'
$(call
make_search,runpy_%)
$(call
make_search,pyrun_%)
$(call
make_search,pypyrun_%)
...
...
from_cpython/Include/abstract.h
View file @
b322d2b2
...
...
@@ -1185,7 +1185,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
#define PySequence_Fast_ITEMS(sf) \
(PyList_Check(sf) ? (PyList_Items(sf)) \
: (
PyTuple_Items(sf))
)
: (
(PyTupleObject *)(sf))->ob_item
)
/* Return a pointer to the underlying item array for
an object retured by PySequence_Fast */
...
...
from_cpython/Include/tupleobject.h
View file @
b322d2b2
...
...
@@ -22,8 +22,6 @@ inserted in the tuple. Similarly, PyTuple_GetItem does not increment the
returned item's reference count.
*/
// Pyston change: this is not the format we're using (but maybe it should be)
#if 0
typedef
struct
{
PyObject_VAR_HEAD
PyObject
*
ob_item
[
1
];
...
...
@@ -33,9 +31,6 @@ typedef struct {
* the tuple is not yet visible outside the function that builds it.
*/
}
PyTupleObject
;
#endif
struct
_PyTupleObject
;
typedef
struct
_PyTupleObject
PyTupleObject
;
// Pyston change: this is no longer a static object
PyAPI_DATA
(
PyTypeObject
*
)
tuple_cls
;
...
...
@@ -54,18 +49,11 @@ PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t) PYSTON_NOEXCEPT;
PyAPI_FUNC
(
PyObject
*
)
PyTuple_Pack
(
Py_ssize_t
,
...)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
void
)
_PyTuple_MaybeUntrack
(
PyObject
*
)
PYSTON_NOEXCEPT
;
// Pyston addition:
PyAPI_FUNC
(
PyObject
**
)
PyTuple_Items
(
PyObject
*
)
PYSTON_NOEXCEPT
;
/* Macro, trading safety for speed */
// Pyston changes: these aren't direct macros any more [they potentially could be though]
#define PyTuple_GET_ITEM(op, i) PyTuple_GetItem(op, i)
#define PyTuple_GET_SIZE(op) PyTuple_Size(op)
//#define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i])
//#define PyTuple_GET_SIZE(op) Py_SIZE(op)
#define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i])
#define PyTuple_GET_SIZE(op) Py_SIZE(op)
/* Macro, *only* to be used to fill in brand new tuples */
#define PyTuple_SET_ITEM(op, i, v) PyTuple_SetItem((PyObject*)op, i, v)
//#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)
#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)
PyAPI_FUNC
(
int
)
PyTuple_ClearFreeList
(
void
)
PYSTON_NOEXCEPT
;
...
...
@@ -73,4 +61,3 @@ PyAPI_FUNC(int) PyTuple_ClearFreeList(void) PYSTON_NOEXCEPT;
}
#endif
#endif
/* !Py_TUPLEOBJECT_H */
src/asm_writing/rewriter.cpp
View file @
b322d2b2
...
...
@@ -263,6 +263,8 @@ void Rewriter::assertArgsInPlace() {
}
void
RewriterVar
::
addGuard
(
uint64_t
val
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
val_var
=
rewriter
->
loadConst
(
val
);
rewriter
->
addAction
([
=
]()
{
rewriter
->
_addGuard
(
this
,
val_var
);
},
{
this
,
val_var
},
ActionType
::
GUARD
);
}
...
...
@@ -291,6 +293,8 @@ void Rewriter::_addGuard(RewriterVar* var, RewriterVar* val_constant) {
}
void
RewriterVar
::
addGuardNotEq
(
uint64_t
val
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
val_var
=
rewriter
->
loadConst
(
val
);
rewriter
->
addAction
([
=
]()
{
rewriter
->
_addGuardNotEq
(
this
,
val_var
);
},
{
this
,
val_var
},
ActionType
::
GUARD
);
}
...
...
@@ -319,6 +323,8 @@ void Rewriter::_addGuardNotEq(RewriterVar* var, RewriterVar* val_constant) {
}
void
RewriterVar
::
addAttrGuard
(
int
offset
,
uint64_t
val
,
bool
negate
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
if
(
!
attr_guards
.
insert
(
std
::
make_tuple
(
offset
,
val
,
negate
)).
second
)
return
;
// duplicate guard detected
RewriterVar
*
val_var
=
rewriter
->
loadConst
(
val
);
...
...
@@ -369,6 +375,8 @@ void Rewriter::_addAttrGuard(RewriterVar* var, int offset, RewriterVar* val_cons
}
RewriterVar
*
RewriterVar
::
getAttr
(
int
offset
,
Location
dest
,
assembler
::
MovType
type
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
result
=
rewriter
->
createNewVar
();
rewriter
->
addAction
([
=
]()
{
rewriter
->
_getAttr
(
result
,
this
,
offset
,
dest
,
type
);
},
{
this
},
ActionType
::
NORMAL
);
return
result
;
...
...
@@ -394,6 +402,8 @@ void Rewriter::_getAttr(RewriterVar* result, RewriterVar* ptr, int offset, Locat
}
RewriterVar
*
RewriterVar
::
getAttrDouble
(
int
offset
,
Location
dest
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
result
=
rewriter
->
createNewVar
();
rewriter
->
addAction
([
=
]()
{
rewriter
->
_getAttrDouble
(
result
,
this
,
offset
,
dest
);
},
{
this
},
ActionType
::
NORMAL
);
return
result
;
...
...
@@ -412,6 +422,8 @@ void Rewriter::_getAttrDouble(RewriterVar* result, RewriterVar* ptr, int offset,
}
RewriterVar
*
RewriterVar
::
getAttrFloat
(
int
offset
,
Location
dest
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
result
=
rewriter
->
createNewVar
();
rewriter
->
addAction
([
=
]()
{
rewriter
->
_getAttrFloat
(
result
,
this
,
offset
,
dest
);
},
{
this
},
ActionType
::
NORMAL
);
return
result
;
...
...
@@ -433,6 +445,8 @@ void Rewriter::_getAttrFloat(RewriterVar* result, RewriterVar* ptr, int offset,
}
RewriterVar
*
RewriterVar
::
cmp
(
AST_TYPE
::
AST_TYPE
cmp_type
,
RewriterVar
*
other
,
Location
dest
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
result
=
rewriter
->
createNewVar
();
rewriter
->
addAction
([
=
]()
{
rewriter
->
_cmp
(
result
,
this
,
cmp_type
,
other
,
dest
);
},
{
this
,
other
},
ActionType
::
NORMAL
);
...
...
@@ -466,6 +480,8 @@ void Rewriter::_cmp(RewriterVar* result, RewriterVar* v1, AST_TYPE::AST_TYPE cmp
}
RewriterVar
*
RewriterVar
::
toBool
(
Location
dest
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
result
=
rewriter
->
createNewVar
();
rewriter
->
addAction
([
=
]()
{
rewriter
->
_toBool
(
result
,
this
,
dest
);
},
{
this
},
ActionType
::
NORMAL
);
return
result
;
...
...
@@ -487,6 +503,8 @@ void Rewriter::_toBool(RewriterVar* result, RewriterVar* var, Location dest) {
}
void
RewriterVar
::
setAttr
(
int
offset
,
RewriterVar
*
val
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
rewriter
->
addAction
([
=
]()
{
rewriter
->
_setAttr
(
this
,
offset
,
val
);
},
{
this
,
val
},
ActionType
::
MUTATION
);
}
...
...
@@ -656,6 +674,8 @@ void Rewriter::_trap() {
}
RewriterVar
*
Rewriter
::
loadConst
(
int64_t
val
,
Location
dest
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*&
const_loader_var
=
const_loader
.
constToVar
[
val
];
if
(
!
const_loader_var
)
{
const_loader_var
=
createNewConstantVar
(
val
);
...
...
@@ -664,12 +684,16 @@ RewriterVar* Rewriter::loadConst(int64_t val, Location dest) {
}
RewriterVar
*
Rewriter
::
call
(
bool
has_side_effects
,
void
*
func_addr
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
::
SmallVector
args
;
RewriterVar
::
SmallVector
args_xmm
;
return
call
(
has_side_effects
,
func_addr
,
args
,
args_xmm
);
}
RewriterVar
*
Rewriter
::
call
(
bool
has_side_effects
,
void
*
func_addr
,
RewriterVar
*
arg0
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
::
SmallVector
args
;
RewriterVar
::
SmallVector
args_xmm
;
args
.
push_back
(
arg0
);
...
...
@@ -677,6 +701,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar*
}
RewriterVar
*
Rewriter
::
call
(
bool
has_side_effects
,
void
*
func_addr
,
RewriterVar
*
arg0
,
RewriterVar
*
arg1
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
::
SmallVector
args
;
RewriterVar
::
SmallVector
args_xmm
;
args
.
push_back
(
arg0
);
...
...
@@ -686,6 +712,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar*
RewriterVar
*
Rewriter
::
call
(
bool
has_side_effects
,
void
*
func_addr
,
RewriterVar
*
arg0
,
RewriterVar
*
arg1
,
RewriterVar
*
arg2
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
::
SmallVector
args
;
RewriterVar
::
SmallVector
args_xmm
;
args
.
push_back
(
arg0
);
...
...
@@ -696,6 +724,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar*
RewriterVar
*
Rewriter
::
call
(
bool
has_side_effects
,
void
*
func_addr
,
RewriterVar
*
arg0
,
RewriterVar
*
arg1
,
RewriterVar
*
arg2
,
RewriterVar
*
arg3
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
::
SmallVector
args
;
RewriterVar
::
SmallVector
args_xmm
;
args
.
push_back
(
arg0
);
...
...
@@ -903,6 +933,8 @@ void Rewriter::_call(RewriterVar* result, bool has_side_effects, void* func_addr
}
void
Rewriter
::
abort
()
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
assert
(
!
finished
);
finished
=
true
;
rewrite
->
abort
();
...
...
@@ -944,6 +976,8 @@ void RewriterVar::releaseIfNoUses() {
}
void
Rewriter
::
commit
()
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
assert
(
!
finished
);
initPhaseEmitting
();
...
...
@@ -1173,6 +1207,8 @@ bool Rewriter::finishAssembly(ICSlotInfo* picked_slot, int continue_offset) {
}
void
Rewriter
::
commitReturning
(
RewriterVar
*
var
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
addAction
([
=
]()
{
var
->
getInReg
(
getReturnDestination
(),
true
/* allow_constant_in_reg */
);
var
->
bumpUse
();
...
...
@@ -1201,6 +1237,8 @@ Location Rewriter::allocScratch() {
}
RewriterVar
*
Rewriter
::
add
(
RewriterVar
*
a
,
int64_t
b
,
Location
dest
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
result
=
createNewVar
();
addAction
([
=
]()
{
this
->
_add
(
result
,
a
,
b
,
dest
);
},
{
a
},
ActionType
::
NORMAL
);
return
result
;
...
...
@@ -1229,6 +1267,8 @@ void Rewriter::_add(RewriterVar* result, RewriterVar* a, int64_t b, Location des
}
RewriterVar
*
Rewriter
::
allocate
(
int
n
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
result
=
createNewVar
();
addAction
([
=
]()
{
this
->
_allocate
(
result
,
n
);
},
{},
ActionType
::
NORMAL
);
return
result
;
...
...
@@ -1275,6 +1315,8 @@ int Rewriter::_allocate(RewriterVar* result, int n) {
}
RewriterVar
*
Rewriter
::
allocateAndCopy
(
RewriterVar
*
array_ptr
,
int
n
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
RewriterVar
*
result
=
createNewVar
();
addAction
([
=
]()
{
this
->
_allocateAndCopy
(
result
,
array_ptr
,
n
);
},
{
array_ptr
},
ActionType
::
NORMAL
);
return
result
;
...
...
@@ -1301,6 +1343,8 @@ void Rewriter::_allocateAndCopy(RewriterVar* result, RewriterVar* array_ptr, int
}
RewriterVar
*
Rewriter
::
allocateAndCopyPlus1
(
RewriterVar
*
first_elem
,
RewriterVar
*
rest_ptr
,
int
n_rest
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
if
(
n_rest
>
0
)
assert
(
rest_ptr
!=
NULL
);
else
...
...
@@ -1697,6 +1741,8 @@ static inline void log_ic_attempts_started(const char* debug_name) {
}
Rewriter
*
Rewriter
::
createRewriter
(
void
*
rtn_addr
,
int
num_args
,
const
char
*
debug_name
)
{
STAT_TIMER
(
t0
,
"us_timer_createrewriter"
,
10
);
ICInfo
*
ic
=
NULL
;
// Horrible non-robust optimization: addresses below this address are probably in the binary (ex the interpreter),
...
...
src/codegen/parser.cpp
View file @
b322d2b2
...
...
@@ -995,7 +995,6 @@ AST_Module* parse_string(const char* code) {
}
AST_Module
*
parse_file
(
const
char
*
fn
)
{
UNAVOIDABLE_STAT_TIMER
(
t0
,
"us_timer_cpyton_parsing"
);
Timer
_t
(
"parsing"
);
if
(
ENABLE_PYPA_PARSER
)
{
...
...
@@ -1116,10 +1115,6 @@ AST_Module* caching_parse_file(const char* fn) {
if
(
result
==
ParseResult
::
PYC_UNWRITABLE
)
return
parse_file
(
fn
);
code
=
stat
(
cache_fn
.
c_str
(),
&
cache_stat
);
if
(
code
!=
0
)
return
parse_file
(
fn
);
}
static
const
int
MAX_TRIES
=
5
;
...
...
@@ -1160,6 +1155,7 @@ AST_Module* caching_parse_file(const char* fn) {
if
(
VERBOSITY
()
||
tries
==
MAX_TRIES
)
{
fprintf
(
stderr
,
"Warning: corrupt or non-Pyston .pyc file found; ignoring
\n
"
);
fprintf
(
stderr
,
"%d %d %d %d
\n
"
,
file_data
[
0
],
file_data
[
1
],
file_data
[
2
],
file_data
[
3
]);
fprintf
(
stderr
,
"%d %d %d %d
\n
"
,
getMagic
()[
0
],
getMagic
()[
1
],
getMagic
()[
2
],
getMagic
()[
3
]);
}
good
=
false
;
}
...
...
@@ -1229,10 +1225,6 @@ AST_Module* caching_parse_file(const char* fn) {
if
(
result
==
ParseResult
::
PYC_UNWRITABLE
)
return
parse_file
(
fn
);
code
=
stat
(
cache_fn
.
c_str
(),
&
cache_stat
);
if
(
code
!=
0
)
return
parse_file
(
fn
);
}
}
}
...
...
src/core/stats.cpp
View file @
b322d2b2
...
...
@@ -53,6 +53,8 @@ StatTimer* StatTimer::createStack(StatTimer& timer) {
}
uint64_t
*
StatTimer
::
getCurrentCounter
()
{
if
(
counter_override
)
return
counter_override
;
if
(
stack
)
return
stack
->
_statcounter
;
return
NULL
;
...
...
src/gc/collector.cpp
View file @
b322d2b2
...
...
@@ -199,8 +199,9 @@ bool isValidGCObject(void* p) {
}
void
setIsPythonObject
(
Box
*
b
)
{
auto
al
=
global_heap
.
getAllocationFromInteriorPointer
(
b
);
assert
(
al
->
user_data
==
(
char
*
)
b
);
assert
(
isValidGCMemory
(
b
));
auto
al
=
GCAllocation
::
fromUserData
(
b
);
if
(
al
->
kind_id
==
GCKind
::
CONSERVATIVE
)
{
al
->
kind_id
=
GCKind
::
CONSERVATIVE_PYTHON
;
}
else
{
...
...
@@ -268,7 +269,12 @@ void GCVisitor::visitPotentialRange(void* const* start, void* const* end) {
while
(
start
<
end
)
{
#if TRACE_GC_MARKING
if
(
global_heap
.
getAllocationFromInteriorPointer
(
*
start
))
{
GC_TRACE_LOG
(
"Found conservative reference to %p from %p
\n
"
,
*
start
,
start
);
if
(
*
start
>=
(
void
*
)
HUGE_ARENA_START
)
GC_TRACE_LOG
(
"Found conservative reference to huge object %p from %p
\n
"
,
*
start
,
start
);
else
if
(
*
start
>=
(
void
*
)
LARGE_ARENA_START
&&
*
start
<
(
void
*
)
HUGE_ARENA_START
)
GC_TRACE_LOG
(
"Found conservative reference to large object %p from %p
\n
"
,
*
start
,
start
);
else
GC_TRACE_LOG
(
"Found conservative reference to %p from %p
\n
"
,
*
start
,
start
);
}
#endif
...
...
@@ -316,10 +322,16 @@ void markPhase() {
// if (VERBOSITY()) printf("Found %d roots\n", stack.size());
while
(
void
*
p
=
stack
.
pop
())
{
GC_TRACE_LOG
(
"Looking at heap object %p
\n
"
,
p
);
assert
(((
intptr_t
)
p
)
%
8
==
0
);
GCAllocation
*
al
=
GCAllocation
::
fromUserData
(
p
);
#if TRACE_GC_MARKING
if
(
al
->
kind_id
==
GCKind
::
PYTHON
||
al
->
kind_id
==
GCKind
::
CONSERVATIVE_PYTHON
)
GC_TRACE_LOG
(
"Looking at %s object %p
\n
"
,
static_cast
<
Box
*>
(
p
)
->
cls
->
tp_name
,
p
);
else
GC_TRACE_LOG
(
"Looking at non-python allocation %p
\n
"
,
p
);
#endif
assert
(
isMarked
(
al
));
// printf("Marking + scanning %p\n", p);
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
b322d2b2
...
...
@@ -360,6 +360,8 @@ Box* sorted(Box* obj, Box* cmp, Box* key, Box** args) {
}
Box
*
isinstance_func
(
Box
*
obj
,
Box
*
cls
)
{
STAT_TIMER
(
t0
,
"us_timer_isinstance_func"
,
10
);
int
rtn
=
PyObject_IsInstance
(
obj
,
cls
);
if
(
rtn
<
0
)
checkAndThrowCAPIException
();
...
...
src/runtime/builtin_modules/sys.cpp
View file @
b322d2b2
...
...
@@ -510,7 +510,7 @@ void setupSys() {
}
void
setupSysEnd
()
{
BoxedTuple
::
GCVector
builtin_module_names
;
std
::
vector
<
Box
*
,
StlCompatAllocator
<
Box
*>>
builtin_module_names
;
for
(
auto
&
p
:
sys_modules_dict
->
d
)
{
builtin_module_names
.
push_back
(
p
.
first
);
}
...
...
src/runtime/classobj.cpp
View file @
b322d2b2
...
...
@@ -246,6 +246,8 @@ Box* classobjStr(Box* _obj) {
}
static
Box
*
_instanceGetattribute
(
Box
*
_inst
,
Box
*
_attr
,
bool
raise_on_missing
)
{
STAT_TIMER
(
t0
,
"us_timer_instance_getattribute"
,
0
);
RELEASE_ASSERT
(
_inst
->
cls
==
instance_cls
,
""
);
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
...
...
src/runtime/code.cpp
View file @
b322d2b2
...
...
@@ -83,7 +83,7 @@ public:
if
(
!
param_names
.
takes_param_names
)
return
EmptyTuple
;
BoxedTuple
::
GCVector
elts
;
std
::
vector
<
Box
*
,
StlCompatAllocator
<
Box
*>>
elts
;
for
(
auto
sr
:
param_names
.
args
)
elts
.
push_back
(
boxString
(
sr
));
if
(
param_names
.
vararg
.
size
())
...
...
src/runtime/descr.cpp
View file @
b322d2b2
...
...
@@ -372,6 +372,8 @@ void BoxedMethodDescriptor::gcHandler(GCVisitor* v, Box* _o) {
}
Box
*
BoxedWrapperDescriptor
::
__get__
(
BoxedWrapperDescriptor
*
self
,
Box
*
inst
,
Box
*
owner
)
{
STAT_TIMER
(
t0
,
"us_timer_boxedwrapperdescriptor_get"
,
20
);
RELEASE_ASSERT
(
self
->
cls
==
wrapperdescr_cls
,
""
);
if
(
inst
==
None
)
...
...
@@ -427,7 +429,7 @@ static Box* wrapperdescrGetDoc(Box* b, void*) {
}
Box
*
BoxedWrapperObject
::
__call__
(
BoxedWrapperObject
*
self
,
Box
*
args
,
Box
*
kwds
)
{
STAT_TIMER
(
t0
,
"us_timer_boxedwrapperobject_
_call__"
,
(
self
->
cls
->
is_user_defined
?
1
:
2
));
STAT_TIMER
(
t0
,
"us_timer_boxedwrapperobject_
call"
,
(
self
->
cls
->
is_user_defined
?
10
:
20
));
assert
(
self
->
cls
==
wrapperobject_cls
);
assert
(
args
->
cls
==
tuple_cls
);
...
...
@@ -454,6 +456,8 @@ Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds
Box
*
BoxedWrapperObject
::
tppCall
(
Box
*
_self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
{
STAT_TIMER
(
t0
,
"us_timer_boxedwrapperobject_call"
,
(
_self
->
cls
->
is_user_defined
?
10
:
20
));
assert
(
_self
->
cls
==
wrapperobject_cls
);
BoxedWrapperObject
*
self
=
static_cast
<
BoxedWrapperObject
*>
(
_self
);
...
...
src/runtime/list.cpp
View file @
b322d2b2
...
...
@@ -435,10 +435,10 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
if
(
v_as_seq
==
NULL
)
throwCAPIException
();
v_size
=
PySequence_Fast_GET_SIZE
(
v_as_seq
);
v_size
=
PySequence_Fast_GET_SIZE
(
(
Box
*
)
v_as_seq
);
// If lv->size is 0, lv->elts->elts is garbage
if
(
v_size
)
v_elts
=
PySequence_Fast_ITEMS
(
v_as_seq
);
v_elts
=
PySequence_Fast_ITEMS
(
(
Box
*
)
v_as_seq
);
else
v_elts
=
NULL
;
}
...
...
src/runtime/objmodel.cpp
View file @
b322d2b2
...
...
@@ -231,9 +231,7 @@ extern "C" void my_assert(bool b) {
}
extern
"C"
bool
isSubclass
(
BoxedClass
*
child
,
BoxedClass
*
parent
)
{
#if EXPENSIVE_STAT_TIMERS
STAT_TIMER
(
t0
,
"us_timer_isSubclass"
,
10
);
#endif
return
PyType_IsSubtype
(
child
,
parent
);
}
...
...
@@ -311,7 +309,7 @@ extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size) {
return
&
l
->
elts
->
elts
[
0
];
}
BoxedTuple
::
GCVector
elts
;
std
::
vector
<
Box
*
,
StlCompatAllocator
<
Box
*>>
elts
;
for
(
auto
e
:
obj
->
pyElements
())
{
elts
.
push_back
(
e
);
if
(
elts
.
size
()
>
expected_size
)
...
...
@@ -1845,6 +1843,29 @@ extern "C" Box* getattr(Box* obj, BoxedString* attr) {
std
::
unique_ptr
<
Rewriter
>
rewriter
(
Rewriter
::
createRewriter
(
__builtin_extract_return_addr
(
__builtin_return_address
(
0
)),
2
,
"getattr"
));
#if 0 && STAT_TIMERS
static uint64_t* st_id = Stats::getStatCounter("us_timer_slowpath_getattr_patchable");
static uint64_t* st_id_nopatch = Stats::getStatCounter("us_timer_slowpath_getattr_nopatch");
static uint64_t* st_id_megamorphic = Stats::getStatCounter("us_timer_slowpath_getattr_megamorphic");
ICInfo* icinfo = getICInfo(__builtin_extract_return_addr(__builtin_return_address(0)));
uint64_t* counter;
if (!icinfo)
counter = st_id_nopatch;
else if (icinfo->isMegamorphic())
counter = st_id_megamorphic;
else {
//counter = Stats::getStatCounter("us_timer_slowpath_getattr_patchable_" + std::string(obj->cls->tp_name));
//counter = Stats::getStatCounter("us_timer_slowpath_getattr_patchable_" + std::string(attr->s()));
counter = st_id;
if (!rewriter.get())
printf("");
}
if (icinfo && icinfo->start_addr == (void*)0x2aaaadb1477b)
printf("");
ScopedStatTimer st(counter, 10);
#endif
Box
*
val
;
if
(
rewriter
.
get
())
{
Location
dest
;
...
...
@@ -3947,6 +3968,8 @@ Box* nonzeroAndBox(Box* b, bool negate) {
}
Box
*
compareInternal
(
Box
*
lhs
,
Box
*
rhs
,
int
op_type
,
CompareRewriteArgs
*
rewrite_args
)
{
STAT_TIMER
(
t0
,
"us_timer_compareinternal"
,
0
);
if
(
op_type
==
AST_TYPE
::
Is
||
op_type
==
AST_TYPE
::
IsNot
)
{
bool
neg
=
(
op_type
==
AST_TYPE
::
IsNot
);
...
...
src/runtime/str.cpp
View file @
b322d2b2
...
...
@@ -329,7 +329,7 @@ extern "C" PyObject* PyString_FromFormat(const char* format, ...) noexcept {
}
extern
"C"
Box
*
strAdd
(
BoxedString
*
lhs
,
Box
*
_rhs
)
{
assert
(
isSubclass
(
lhs
->
cls
,
str_cl
s
));
assert
(
PyString_Check
(
lh
s
));
if
(
isSubclass
(
_rhs
->
cls
,
unicode_cls
))
{
Box
*
rtn
=
PyUnicode_Concat
(
lhs
,
_rhs
);
...
...
@@ -337,7 +337,7 @@ extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) {
return
rtn
;
}
if
(
!
isSubclass
(
_rhs
->
cls
,
str_cl
s
))
{
if
(
!
PyString_Check
(
_rh
s
))
{
// Note: this is deliberately not returning NotImplemented, even though
// that would be more usual. I assume this behavior of CPython's is
// for backwards compatibility.
...
...
@@ -1140,7 +1140,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
}
extern
"C"
Box
*
strMul
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
assert
(
isSubclass
(
lhs
->
cls
,
str_cl
s
));
assert
(
PyString_Check
(
lh
s
));
int
n
;
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
...
...
@@ -1160,7 +1160,7 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
}
Box
*
str_richcompare
(
Box
*
lhs
,
Box
*
rhs
,
int
op
)
{
assert
(
isSubclass
(
lhs
->
cls
,
str_cl
s
));
assert
(
PyString_Check
(
lh
s
));
// Note: it is somehow about 50% faster to do this check inside the switch
// statement, rather than out here. It's functionally equivalent but the
...
...
@@ -1206,7 +1206,7 @@ Box* str_richcompare(Box* lhs, Box* rhs, int op) {
#define JUST_CENTER 2
static
Box
*
pad
(
BoxedString
*
self
,
Box
*
width
,
Box
*
fillchar
,
int
justType
)
{
assert
(
width
->
cls
==
int_cls
);
assert
(
isSubclass
(
fillchar
->
cls
,
str_cls
));
assert
(
PyString_Check
(
fillchar
));
assert
(
static_cast
<
BoxedString
*>
(
fillchar
)
->
size
()
==
1
);
int64_t
curWidth
=
self
->
size
();
int64_t
targetWidth
=
static_cast
<
BoxedInt
*>
(
width
)
->
n
;
...
...
@@ -1255,13 +1255,13 @@ extern "C" Box* strCenter(BoxedString* lhs, Box* width, Box* fillchar) {
}
extern
"C"
Box
*
strLen
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
return
boxInt
(
self
->
size
());
}
extern
"C"
Box
*
strStr
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
if
(
self
->
cls
==
str_cls
)
return
self
;
...
...
@@ -1290,7 +1290,7 @@ static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but cla
extern
"C"
PyObject
*
PyString_Repr
(
PyObject
*
obj
,
int
smartquotes
)
noexcept
{
BoxedString
*
self
=
(
BoxedString
*
)
obj
;
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
std
::
ostringstream
os
(
""
);
...
...
@@ -1534,14 +1534,14 @@ extern "C" size_t unicodeHashUnboxed(PyUnicodeObject* self) {
}
extern
"C"
Box
*
strHash
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
StringHash
<
char
>
H
;
return
boxInt
(
H
(
self
->
data
(),
self
->
size
()));
}
extern
"C"
Box
*
strNonzero
(
BoxedString
*
self
)
{
ASSERT
(
isSubclass
(
self
->
cls
,
str_cls
),
"%s"
,
self
->
cls
->
tp_name
);
ASSERT
(
PyString_Check
(
self
),
"%s"
,
self
->
cls
->
tp_name
);
return
boxBool
(
self
->
size
()
!=
0
);
}
...
...
@@ -1550,7 +1550,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) {
assert
(
isSubclass
(
cls
,
str_cls
));
Box
*
rtn
=
str
(
obj
);
assert
(
isSubclass
(
rtn
->
cls
,
str_cls
));
assert
(
PyString_Check
(
rtn
));
if
(
cls
==
str_cls
)
return
rtn
;
...
...
@@ -1565,7 +1565,7 @@ extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
}
Box
*
_strSlice
(
BoxedString
*
self
,
i64
start
,
i64
stop
,
i64
step
,
i64
length
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
llvm
::
StringRef
s
=
self
->
s
();
...
...
@@ -1587,7 +1587,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
}
Box
*
strIsAlpha
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
llvm
::
StringRef
str
(
self
->
s
());
if
(
str
.
empty
())
...
...
@@ -1602,7 +1602,7 @@ Box* strIsAlpha(BoxedString* self) {
}
Box
*
strIsDigit
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
llvm
::
StringRef
str
(
self
->
s
());
if
(
str
.
empty
())
...
...
@@ -1617,7 +1617,7 @@ Box* strIsDigit(BoxedString* self) {
}
Box
*
strIsAlnum
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
llvm
::
StringRef
str
(
self
->
s
());
if
(
str
.
empty
())
...
...
@@ -1632,7 +1632,7 @@ Box* strIsAlnum(BoxedString* self) {
}
Box
*
strIsLower
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
llvm
::
StringRef
str
(
self
->
s
());
bool
lowered
=
false
;
...
...
@@ -1654,7 +1654,7 @@ Box* strIsLower(BoxedString* self) {
}
Box
*
strIsUpper
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
llvm
::
StringRef
str
(
self
->
s
());
...
...
@@ -1673,7 +1673,7 @@ Box* strIsUpper(BoxedString* self) {
}
Box
*
strIsSpace
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
llvm
::
StringRef
str
(
self
->
s
());
if
(
str
.
empty
())
...
...
@@ -1688,7 +1688,7 @@ Box* strIsSpace(BoxedString* self) {
}
Box
*
strIsTitle
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
llvm
::
StringRef
str
(
self
->
s
());
...
...
@@ -1723,12 +1723,12 @@ Box* strIsTitle(BoxedString* self) {
}
extern
"C"
PyObject
*
_PyString_Join
(
PyObject
*
sep
,
PyObject
*
x
)
noexcept
{
RELEASE_ASSERT
(
isSubclass
(
sep
->
cls
,
str_cls
),
""
);
RELEASE_ASSERT
(
PyString_Check
(
sep
),
""
);
return
string_join
((
PyStringObject
*
)
sep
,
x
);
}
Box
*
strReplace
(
Box
*
_self
,
Box
*
_old
,
Box
*
_new
,
Box
**
_args
)
{
if
(
!
isSubclass
(
_self
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
_self
))
raiseExcHelper
(
TypeError
,
"descriptor 'replace' requires a 'str' object but received a '%s'"
,
getTypeName
(
_self
));
BoxedString
*
self
=
static_cast
<
BoxedString
*>
(
_self
);
...
...
@@ -1738,11 +1738,11 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
return
PyUnicode_Replace
((
PyObject
*
)
self
,
_old
,
_new
,
-
1
/*count*/
);
#endif
if
(
!
isSubclass
(
_old
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
_old
))
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
BoxedString
*
old
=
static_cast
<
BoxedString
*>
(
_old
);
if
(
!
isSubclass
(
_new
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
_new
))
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
BoxedString
*
new_
=
static_cast
<
BoxedString
*>
(
_new
);
...
...
@@ -1764,8 +1764,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
}
Box
*
strPartition
(
BoxedString
*
self
,
BoxedString
*
sep
)
{
RELEASE_ASSERT
(
isSubclass
(
self
->
cls
,
str_cls
),
""
);
RELEASE_ASSERT
(
isSubclass
(
sep
->
cls
,
str_cls
),
""
);
RELEASE_ASSERT
(
PyString_Check
(
self
),
""
);
RELEASE_ASSERT
(
PyString_Check
(
sep
),
""
);
size_t
found_idx
=
self
->
s
().
find
(
sep
->
s
());
if
(
found_idx
==
std
::
string
::
npos
)
...
...
@@ -1779,8 +1779,8 @@ Box* strPartition(BoxedString* self, BoxedString* sep) {
}
Box
*
strRpartition
(
BoxedString
*
self
,
BoxedString
*
sep
)
{
RELEASE_ASSERT
(
isSubclass
(
self
->
cls
,
str_cls
),
""
);
RELEASE_ASSERT
(
isSubclass
(
sep
->
cls
,
str_cls
),
""
);
RELEASE_ASSERT
(
PyString_Check
(
self
),
""
);
RELEASE_ASSERT
(
PyString_Check
(
sep
),
""
);
size_t
found_idx
=
self
->
s
().
rfind
(
sep
->
s
());
if
(
found_idx
==
std
::
string
::
npos
)
...
...
@@ -1805,10 +1805,10 @@ Box* strFormat(BoxedString* self, BoxedTuple* args, BoxedDict* kwargs) {
}
Box
*
strStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
auto
str
=
self
->
s
();
if
(
isSubclass
(
chars
->
cls
,
str_cl
s
))
{
if
(
PyString_Check
(
char
s
))
{
auto
chars_str
=
static_cast
<
BoxedString
*>
(
chars
)
->
s
();
return
boxString
(
str
.
trim
(
chars_str
));
}
else
if
(
chars
->
cls
==
none_cls
)
{
...
...
@@ -1829,10 +1829,10 @@ Box* strStrip(BoxedString* self, Box* chars) {
}
Box
*
strLStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
auto
str
=
self
->
s
();
if
(
isSubclass
(
chars
->
cls
,
str_cl
s
))
{
if
(
PyString_Check
(
char
s
))
{
auto
chars_str
=
static_cast
<
BoxedString
*>
(
chars
)
->
s
();
return
boxString
(
str
.
ltrim
(
chars_str
));
}
else
if
(
chars
->
cls
==
none_cls
)
{
...
...
@@ -1853,10 +1853,10 @@ Box* strLStrip(BoxedString* self, Box* chars) {
}
Box
*
strRStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
auto
str
=
self
->
s
();
if
(
isSubclass
(
chars
->
cls
,
str_cl
s
))
{
if
(
PyString_Check
(
char
s
))
{
auto
chars_str
=
static_cast
<
BoxedString
*>
(
chars
)
->
s
();
return
boxString
(
str
.
rtrim
(
chars_str
));
}
else
if
(
chars
->
cls
==
none_cls
)
{
...
...
@@ -1877,7 +1877,7 @@ Box* strRStrip(BoxedString* self, Box* chars) {
}
Box
*
strCapitalize
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
std
::
string
s
(
self
->
s
());
...
...
@@ -1893,7 +1893,7 @@ Box* strCapitalize(BoxedString* self) {
}
Box
*
strTitle
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
std
::
string
s
(
self
->
s
());
bool
start_of_word
=
false
;
...
...
@@ -1917,20 +1917,20 @@ Box* strTitle(BoxedString* self) {
}
Box
*
strTranslate
(
BoxedString
*
self
,
BoxedString
*
table
,
BoxedString
*
delete_chars
)
{
if
(
!
isSubclass
(
self
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor 'translate' requires a 'str' object but received a '%s'"
,
getTypeName
(
self
));
std
::
unordered_set
<
char
>
delete_set
;
if
(
delete_chars
)
{
if
(
!
isSubclass
(
delete_chars
->
cls
,
str_cl
s
))
if
(
!
PyString_Check
(
delete_char
s
))
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
delete_set
.
insert
(
delete_chars
->
s
().
begin
(),
delete_chars
->
s
().
end
());
}
bool
have_table
=
table
!=
None
;
if
(
have_table
)
{
if
(
!
isSubclass
(
table
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
table
))
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
if
(
table
->
size
()
!=
256
)
raiseExcHelper
(
ValueError
,
"translation table must be 256 characters long"
);
...
...
@@ -1945,7 +1945,7 @@ Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_cha
}
Box
*
strLower
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
BoxedString
*
rtn
=
new
(
self
->
size
())
BoxedString
(
self
->
s
());
for
(
int
i
=
0
;
i
<
rtn
->
size
();
i
++
)
...
...
@@ -1954,7 +1954,7 @@ Box* strLower(BoxedString* self) {
}
Box
*
strUpper
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
BoxedString
*
rtn
=
new
(
self
->
size
())
BoxedString
(
self
->
s
());
for
(
int
i
=
0
;
i
<
rtn
->
size
();
i
++
)
rtn
->
data
()[
i
]
=
std
::
toupper
(
rtn
->
data
()[
i
]);
...
...
@@ -1962,7 +1962,7 @@ Box* strUpper(BoxedString* self) {
}
Box
*
strSwapcase
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
BoxedString
*
rtn
=
new
(
self
->
size
())
BoxedString
(
self
->
s
());
for
(
int
i
=
0
;
i
<
rtn
->
size
();
i
++
)
{
char
c
=
rtn
->
data
()[
i
];
...
...
@@ -1975,7 +1975,7 @@ Box* strSwapcase(BoxedString* self) {
}
Box
*
strContains
(
BoxedString
*
self
,
Box
*
elt
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
if
(
PyUnicode_Check
(
elt
))
{
int
r
=
PyUnicode_Contains
(
self
,
elt
);
...
...
@@ -1984,7 +1984,7 @@ Box* strContains(BoxedString* self, Box* elt) {
return
boxBool
(
r
);
}
if
(
!
isSubclass
(
elt
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
elt
))
raiseExcHelper
(
TypeError
,
"'in <string>' requires string as left operand, not %s"
,
getTypeName
(
elt
));
BoxedString
*
sub
=
static_cast
<
BoxedString
*>
(
elt
);
...
...
@@ -2016,7 +2016,7 @@ extern "C" int _PyString_Eq(PyObject* o1, PyObject* o2) noexcept {
Box
*
strStartswith
(
BoxedString
*
self
,
Box
*
elt
,
Box
*
start
,
Box
**
_args
)
{
Box
*
end
=
_args
[
0
];
if
(
!
isSubclass
(
self
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor 'startswith' requires a 'str' object but received a '%s'"
,
getTypeName
(
self
));
...
...
@@ -2051,7 +2051,7 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
return
boxBool
(
r
);
}
if
(
!
isSubclass
(
elt
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
elt
))
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
BoxedString
*
sub
=
static_cast
<
BoxedString
*>
(
elt
);
...
...
@@ -2079,7 +2079,7 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
Box
*
strEndswith
(
BoxedString
*
self
,
Box
*
elt
,
Box
*
start
,
Box
**
_args
)
{
Box
*
end
=
_args
[
0
];
if
(
!
isSubclass
(
self
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor 'endswith' requires a 'str' object but received a '%s'"
,
getTypeName
(
self
));
...
...
@@ -2114,7 +2114,7 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
return
False
;
}
if
(
!
isSubclass
(
elt
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
elt
))
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
BoxedString
*
sub
=
static_cast
<
BoxedString
*>
(
elt
);
...
...
@@ -2142,7 +2142,7 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
}
Box
*
strDecode
(
BoxedString
*
self
,
Box
*
encoding
,
Box
*
error
)
{
if
(
!
isSubclass
(
self
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor 'decode' requires a 'str' object but received a '%s'"
,
getTypeName
(
self
));
BoxedString
*
encoding_str
=
(
BoxedString
*
)
encoding
;
...
...
@@ -2151,13 +2151,13 @@ Box* strDecode(BoxedString* self, Box* encoding, Box* error) {
if
(
encoding_str
&&
encoding_str
->
cls
==
unicode_cls
)
encoding_str
=
(
BoxedString
*
)
_PyUnicode_AsDefaultEncodedString
(
encoding_str
,
NULL
);
if
(
encoding_str
&&
!
isSubclass
(
encoding_str
->
cls
,
str_cls
))
if
(
encoding_str
&&
!
PyString_Check
(
encoding_str
))
raiseExcHelper
(
TypeError
,
"decode() argument 1 must be string, not '%s'"
,
getTypeName
(
encoding_str
));
if
(
error_str
&&
error_str
->
cls
==
unicode_cls
)
error_str
=
(
BoxedString
*
)
_PyUnicode_AsDefaultEncodedString
(
error_str
,
NULL
);
if
(
error_str
&&
!
isSubclass
(
error_str
->
cls
,
str_cls
))
if
(
error_str
&&
!
PyString_Check
(
error_str
))
raiseExcHelper
(
TypeError
,
"decode() argument 2 must be string, not '%s'"
,
getTypeName
(
error_str
));
Box
*
result
=
PyString_AsDecodedObject
(
self
,
encoding_str
?
encoding_str
->
data
()
:
NULL
,
...
...
@@ -2167,7 +2167,7 @@ Box* strDecode(BoxedString* self, Box* encoding, Box* error) {
}
Box
*
strEncode
(
BoxedString
*
self
,
Box
*
encoding
,
Box
*
error
)
{
if
(
!
isSubclass
(
self
->
cls
,
str_cls
))
if
(
!
PyString_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor 'encode' requires a 'str' object but received a '%s'"
,
getTypeName
(
self
));
BoxedString
*
encoding_str
=
(
BoxedString
*
)
encoding
;
...
...
@@ -2176,13 +2176,13 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
if
(
encoding_str
&&
encoding_str
->
cls
==
unicode_cls
)
encoding_str
=
(
BoxedString
*
)
_PyUnicode_AsDefaultEncodedString
(
encoding_str
,
NULL
);
if
(
encoding_str
&&
!
isSubclass
(
encoding_str
->
cls
,
str_cls
))
if
(
encoding_str
&&
!
PyString_Check
(
encoding_str
))
raiseExcHelper
(
TypeError
,
"encode() argument 1 must be string, not '%s'"
,
getTypeName
(
encoding_str
));
if
(
error_str
&&
error_str
->
cls
==
unicode_cls
)
error_str
=
(
BoxedString
*
)
_PyUnicode_AsDefaultEncodedString
(
error_str
,
NULL
);
if
(
error_str
&&
!
isSubclass
(
error_str
->
cls
,
str_cls
))
if
(
error_str
&&
!
PyString_Check
(
error_str
))
raiseExcHelper
(
TypeError
,
"encode() argument 2 must be string, not '%s'"
,
getTypeName
(
error_str
));
Box
*
result
=
PyString_AsEncodedObject
(
self
,
encoding_str
?
encoding_str
->
data
()
:
PyUnicode_GetDefaultEncoding
(),
...
...
@@ -2192,7 +2192,7 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
}
extern
"C"
Box
*
strGetitem
(
BoxedString
*
self
,
Box
*
slice
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
if
(
PyIndex_Check
(
slice
))
{
Py_ssize_t
n
=
PyNumber_AsSsize_t
(
slice
,
PyExc_IndexError
);
...
...
@@ -2267,7 +2267,7 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) {
}
Box
*
strIter
(
BoxedString
*
self
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
return
new
BoxedStringIterator
(
self
);
}
...
...
@@ -2338,7 +2338,7 @@ extern "C" char* PyString_AsString(PyObject* o) noexcept {
}
extern
"C"
Py_ssize_t
PyString_Size
(
PyObject
*
op
)
noexcept
{
if
(
isSubclass
(
op
->
cls
,
str_cls
))
if
(
PyString_Check
(
op
))
return
static_cast
<
BoxedString
*>
(
op
)
->
size
();
char
*
_s
;
...
...
@@ -2362,7 +2362,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
// This is only allowed to be called when there is only one user of the string (ie a refcount of 1 in CPython)
assert
(
pv
);
assert
(
isSubclass
((
*
pv
)
->
cls
,
str_cls
));
assert
(
PyString_Check
(
*
pv
));
BoxedString
*
s
=
static_cast
<
BoxedString
*>
(
*
pv
);
if
(
newsize
==
s
->
size
())
...
...
@@ -2609,7 +2609,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
RELEASE_ASSERT
(
index
==
0
,
""
);
// I think maybe this can just be a non-release assert? shouldn't be able to call this with
// the wrong type
RELEASE_ASSERT
(
isSubclass
(
self
->
cls
,
str_cls
),
""
);
RELEASE_ASSERT
(
PyString_Check
(
self
),
""
);
auto
s
=
static_cast
<
BoxedString
*>
(
self
);
*
ptr
=
s
->
data
();
...
...
@@ -2618,7 +2618,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
static
Py_ssize_t
string_buffer_getsegcount
(
PyObject
*
o
,
Py_ssize_t
*
lenp
)
noexcept
{
RELEASE_ASSERT
(
lenp
==
NULL
,
""
);
RELEASE_ASSERT
(
isSubclass
(
o
->
cls
,
str_cls
),
""
);
RELEASE_ASSERT
(
PyString_Check
(
o
),
""
);
return
1
;
}
...
...
@@ -2632,7 +2632,7 @@ static Py_ssize_t string_buffer_getcharbuf(PyStringObject* self, Py_ssize_t inde
}
static
int
string_buffer_getbuffer
(
BoxedString
*
self
,
Py_buffer
*
view
,
int
flags
)
noexcept
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
PyString_Check
(
self
));
return
PyBuffer_FillInfo
(
view
,
(
PyObject
*
)
self
,
self
->
data
(),
self
->
size
(),
1
,
flags
);
}
...
...
src/runtime/tuple.cpp
View file @
b322d2b2
...
...
@@ -69,12 +69,6 @@ Box* tupleGetitemInt(BoxedTuple* self, BoxedInt* slice) {
return
tupleGetitemUnboxed
(
self
,
slice
->
n
);
}
extern
"C"
PyObject
**
PyTuple_Items
(
PyObject
*
op
)
noexcept
{
RELEASE_ASSERT
(
PyTuple_Check
(
op
),
""
);
return
&
static_cast
<
BoxedTuple
*>
(
op
)
->
elts
[
0
];
}
extern
"C"
PyObject
*
PyTuple_GetItem
(
PyObject
*
op
,
Py_ssize_t
i
)
noexcept
{
RELEASE_ASSERT
(
PyTuple_Check
(
op
),
""
);
RELEASE_ASSERT
(
i
>=
0
,
""
);
// unlike tuple.__getitem__, PyTuple_GetItem doesn't do index wrapping
...
...
src/runtime/types.cpp
View file @
b322d2b2
...
...
@@ -202,7 +202,8 @@ void* BoxVar::operator new(size_t size, BoxedClass* cls, size_t nitems) {
ALLOC_STATS_VAR
(
cls
);
assert
(
cls
);
ASSERT
(
cls
->
tp_basicsize
>=
size
,
"%s"
,
cls
->
tp_name
);
// See definition of BoxedTuple for some notes on why we need this special case:
ASSERT
(
isSubclass
(
cls
,
tuple_cls
)
||
cls
->
tp_basicsize
>=
size
,
"%s"
,
cls
->
tp_name
);
assert
(
cls
->
tp_itemsize
>
0
);
assert
(
cls
->
tp_alloc
);
...
...
@@ -516,6 +517,8 @@ void BoxedModule::gcHandler(GCVisitor* v, Box* b) {
// TODO: should we use C++11 `noexcept' here?
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
Box
*
globals
,
std
::
initializer_list
<
Box
*>
defaults
)
{
STAT_TIMER
(
t0
,
"us_timer_boxclfunction"
,
10
);
if
(
closure
)
assert
(
closure
->
cls
==
closure_cls
);
...
...
@@ -2909,8 +2912,10 @@ void setupRuntime() {
object_cls
->
giveAttr
(
"__base__"
,
None
);
// Not sure why CPython defines sizeof(PyTupleObject) to include one element,
// but we copy that, which means we have to subtract that extra pointer to get the tp_basicsize:
tuple_cls
=
new
(
0
)
BoxedHeapClass
(
object_cls
,
&
tupleGCHandler
,
0
,
0
,
sizeof
(
BoxedTuple
),
false
,
boxString
(
"tuple"
));
BoxedHeapClass
(
object_cls
,
&
tupleGCHandler
,
0
,
0
,
sizeof
(
BoxedTuple
)
-
sizeof
(
Box
*
)
,
false
,
boxString
(
"tuple"
));
tuple_cls
->
tp_flags
|=
Py_TPFLAGS_TUPLE_SUBCLASS
;
tuple_cls
->
tp_itemsize
=
sizeof
(
Box
*
);
tuple_cls
->
tp_mro
=
BoxedTuple
::
create
({
tuple_cls
,
object_cls
});
...
...
src/runtime/types.h
View file @
b322d2b2
...
...
@@ -554,10 +554,6 @@ public:
class
BoxedTuple
:
public
BoxVar
{
public:
typedef
std
::
vector
<
Box
*
,
StlCompatAllocator
<
Box
*>>
GCVector
;
DEFAULT_CLASS_VAR_SIMPLE
(
tuple_cls
,
sizeof
(
Box
*
));
static
BoxedTuple
*
create
(
int64_t
size
)
{
return
new
(
size
)
BoxedTuple
(
size
);
}
static
BoxedTuple
*
create
(
int64_t
nelts
,
Box
**
elts
)
{
BoxedTuple
*
rtn
=
new
(
nelts
)
BoxedTuple
(
nelts
);
...
...
@@ -584,14 +580,26 @@ public:
}
static
BoxedTuple
*
create
(
std
::
initializer_list
<
Box
*>
members
)
{
return
new
(
members
.
size
())
BoxedTuple
(
members
);
}
static
BoxedTuple
*
create
(
int64_t
size
,
BoxedClass
*
cls
)
{
return
new
(
cls
,
size
)
BoxedTuple
(
size
);
}
static
BoxedTuple
*
create
(
int64_t
size
,
BoxedClass
*
cls
)
{
if
(
cls
==
tuple_cls
)
return
new
(
size
)
BoxedTuple
(
size
);
else
return
new
(
cls
,
size
)
BoxedTuple
(
size
);
}
static
BoxedTuple
*
create
(
int64_t
nelts
,
Box
**
elts
,
BoxedClass
*
cls
)
{
BoxedTuple
*
rtn
=
new
(
cls
,
nelts
)
BoxedTuple
(
nelts
);
BoxedTuple
*
rtn
;
if
(
cls
==
tuple_cls
)
rtn
=
new
(
nelts
)
BoxedTuple
(
nelts
);
else
rtn
=
new
(
cls
,
nelts
)
BoxedTuple
(
nelts
);
memmove
(
&
rtn
->
elts
[
0
],
elts
,
sizeof
(
Box
*
)
*
nelts
);
return
rtn
;
}
static
BoxedTuple
*
create
(
std
::
initializer_list
<
Box
*>
members
,
BoxedClass
*
cls
)
{
return
new
(
cls
,
members
.
size
())
BoxedTuple
(
members
);
if
(
cls
==
tuple_cls
)
return
new
(
members
.
size
())
BoxedTuple
(
members
);
else
return
new
(
cls
,
members
.
size
())
BoxedTuple
(
members
);
}
static
int
Resize
(
BoxedTuple
**
pt
,
size_t
newsize
)
noexcept
;
...
...
@@ -602,6 +610,32 @@ public:
size_t
size
()
const
{
return
ob_size
;
}
// DEFAULT_CLASS_VAR_SIMPLE doesn't work because of declaring 1 element in 'elts'
void
*
operator
new
(
size_t
size
,
BoxedClass
*
cls
,
size_t
nitems
)
__attribute__
((
visibility
(
"default"
)))
{
ALLOC_STATS_VAR
(
tuple_cls
)
assert
(
cls
->
tp_itemsize
==
sizeof
(
Box
*
));
return
BoxVar
::
operator
new
(
size
,
cls
,
nitems
);
}
void
*
operator
new
(
size_t
size
,
size_t
nitems
)
__attribute__
((
visibility
(
"default"
)))
{
ALLOC_STATS_VAR
(
tuple_cls
)
assert
(
tuple_cls
->
tp_alloc
==
PystonType_GenericAlloc
);
assert
(
tuple_cls
->
tp_itemsize
==
sizeof
(
Box
*
));
assert
(
tuple_cls
->
tp_basicsize
==
offsetof
(
BoxedTuple
,
elts
));
assert
(
tuple_cls
->
is_pyston_class
);
assert
(
tuple_cls
->
attrs_offset
==
0
);
void
*
mem
=
gc_alloc
(
sizeof
(
BoxedTuple
)
+
nitems
*
sizeof
(
Box
*
),
gc
::
GCKind
::
PYTHON
);
assert
(
mem
);
BoxVar
*
rtn
=
static_cast
<
BoxVar
*>
(
mem
);
rtn
->
cls
=
tuple_cls
;
rtn
->
ob_size
=
nitems
;
return
rtn
;
}
private:
BoxedTuple
(
size_t
size
)
{
memset
(
elts
,
0
,
sizeof
(
Box
*
)
*
size
);
}
...
...
@@ -614,8 +648,18 @@ private:
}
public:
Box
*
elts
[
0
];
// CPython declares ob_item (their version of elts) to have 1 element. We want to
// copy that behavior so that the sizes of the objects match, but we want to also
// have a zero-length array in there since we have some extra compiler warnings turned
// on. _elts[1] will throw an error, but elts[1] will not.
union
{
Box
*
elts
[
0
];
Box
*
_elts
[
1
];
};
};
static_assert
(
sizeof
(
BoxedTuple
)
==
sizeof
(
PyTupleObject
),
""
);
static_assert
(
offsetof
(
BoxedTuple
,
ob_size
)
==
offsetof
(
PyTupleObject
,
ob_size
),
""
);
static_assert
(
offsetof
(
BoxedTuple
,
elts
)
==
offsetof
(
PyTupleObject
,
ob_item
),
""
);
extern
"C"
BoxedTuple
*
EmptyTuple
;
extern
"C"
BoxedString
*
EmptyString
;
...
...
test/extra/pyicu_101.patch
View file @
b322d2b2
diff -ur PyICU-1.0.1_o/common.h PyICU-1.0.1/common.h
--- PyICU-1.0.1_o/common.h 2010-03-29 20:04:02.000000000 +0200
+++ PyICU-1.0.1/common.h 2015-05-18 22:38:10.625582065 +0200
@@ -199,9 +199,15 @@
#else
+// Pyston change:
+/*
#define parseArgs(args, types, rest...) \
_parseArgs(((PyTupleObject *)(args))->ob_item, \
((PyTupleObject *)(args))->ob_size, types, ##rest)
+*/
+#define parseArgs(args, types, rest...) \
+ _parseArgs(PyTuple_Items(args), PyTuple_Size(args), types, ##rest)
+
#define parseArg(arg, types, rest...) \
_parseArgs(&(arg), 1, types, ##rest)
diff -ur PyICU-1.0.1_o/_icu.cpp PyICU-1.0.1/_icu.cpp
--- PyICU-1.0.1_o/_icu.cpp 2010-04-02 00:12:54.000000000 +0200
+++ PyICU-1.0.1/_icu.cpp 2015-05-19 15:26:15.131375981 +0200
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment