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
e1430c45
Commit
e1430c45
authored
Feb 24, 2016
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Lots of improvements
parent
c6c87982
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
85 additions
and
42 deletions
+85
-42
src/asm_writing/rewriter.cpp
src/asm_writing/rewriter.cpp
+17
-3
src/asm_writing/rewriter.h
src/asm_writing/rewriter.h
+5
-0
src/codegen/compvars.cpp
src/codegen/compvars.cpp
+13
-4
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+11
-7
src/codegen/irgen/refcounts.cpp
src/codegen/irgen/refcounts.cpp
+14
-10
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+23
-16
src/runtime/types.h
src/runtime/types.h
+2
-2
No files found.
src/asm_writing/rewriter.cpp
View file @
e1430c45
...
...
@@ -513,6 +513,7 @@ void RewriterVar::xdecref() {
}
void
Rewriter
::
_incref
(
RewriterVar
*
var
)
{
assert
(
!
var
->
nullable
);
//assembler->trap();
//auto reg = var->getInReg();
//assembler->incl(assembler::Indirect(reg, offsetof(Box, ob_refcnt)));
...
...
@@ -533,6 +534,7 @@ void Rewriter::_incref(RewriterVar* var) {
}
void
Rewriter
::
_decref
(
RewriterVar
*
var
)
{
assert
(
!
var
->
nullable
);
//assembler->trap();
//this->_call(NULL, true, (void*)Helper::decref, llvm::ArrayRef<RewriterVar*>(&var, 1),
...
...
@@ -563,6 +565,7 @@ void Rewriter::_decref(RewriterVar* var) {
}
void
Rewriter
::
_xdecref
(
RewriterVar
*
var
)
{
assert
(
var
->
nullable
);
//assembler->trap();
this
->
_call
(
NULL
,
true
,
(
void
*
)
Helper
::
xdecref
,
llvm
::
ArrayRef
<
RewriterVar
*>
(
&
var
,
1
),
...
...
@@ -1206,8 +1209,12 @@ RewriterVar* RewriterVar::setType(RefType type) {
}
void
RewriterVar
::
_release
()
{
if
(
reftype
==
RefType
::
OWNED
&&
!
this
->
refHandedOff
())
this
->
rewriter
->
_decref
(
this
);
if
(
reftype
==
RefType
::
OWNED
&&
!
this
->
refHandedOff
())
{
if
(
nullable
)
this
->
rewriter
->
_xdecref
(
this
);
else
this
->
rewriter
->
_decref
(
this
);
}
for
(
Location
loc
:
locations
)
{
rewriter
->
vars_by_location
.
erase
(
loc
);
...
...
@@ -1849,7 +1856,14 @@ assembler::Register Rewriter::allocReg(Location dest, Location otherThan) {
if
(
!
done_guarding
&&
var
->
is_arg
&&
var
->
arg_loc
==
Location
(
reg
))
{
continue
;
}
if
(
var
->
uses
[
var
->
next_use
]
>
best
)
{
if
(
var
->
next_use
==
var
->
uses
.
size
())
{
// If we found a variable that is dead but somehow occupying a location,
// don't touch it.
// This could be something that we are actively working on decref'ing.
continue
;
}
else
if
(
var
->
uses
[
var
->
next_use
]
>
best
)
{
found
=
true
;
best
=
var
->
uses
[
var
->
next_use
];
best_reg
=
reg
;
...
...
src/asm_writing/rewriter.h
View file @
e1430c45
...
...
@@ -208,6 +208,7 @@ class RewriterVar {
int
num_refs_consumed
=
0
;
// The number of "refConsumed()" calls on this RewriterVar
int
last_refconsumed_numuses
=
0
;
// The number of uses in the `uses` array when the last refConsumed() call was made.
RefType
reftype
=
RefType
::
UNKNOWN
;
bool
nullable
=
false
;
// Helper function: whether there is a ref that got consumed but came from the consumption of the
// initial (owned) reference.
bool
refHandedOff
();
...
...
@@ -227,6 +228,10 @@ public:
RewriterVar
*
toBool
(
Location
loc
=
Location
::
any
());
RewriterVar
*
setType
(
RefType
type
);
RewriterVar
*
setNullable
(
bool
nullable
)
{
this
->
nullable
=
nullable
;
return
this
;
}
// Call this to let the automatic refcount machinery know that a refcount
// got "consumed", ie passed off. Such as to a function that steals a reference,
...
...
src/codegen/compvars.cpp
View file @
e1430c45
...
...
@@ -406,15 +406,17 @@ public:
llvm
::
Value
*
uncasted
=
emitter
.
createIC
(
pp
,
(
void
*
)
pyston
::
createBoxedIterWrapperIfNeeded
,
{
converted_iter_call
->
getValue
()
},
info
.
unw_info
);
llvm
::
Value
*
value_has_iter
=
emitter
.
getBuilder
()
->
CreateIntToPtr
(
uncasted
,
g
.
llvm_value_type_ptr
);
emitter
.
setType
(
value_has_iter
,
RefType
::
OWNED
);
llvm
::
BasicBlock
*
value_has_iter_bb
=
emitter
.
currentBasicBlock
();
emitter
.
getBuilder
()
->
CreateBr
(
bb_join
);
auto
has_iter_terminator
=
emitter
.
getBuilder
()
->
CreateBr
(
bb_join
);
// var has no __iter__()
// TODO: we could create a patchpoint if this turns out to be hot
emitter
.
setCurrentBasicBlock
(
bb_no_iter
);
llvm
::
Value
*
value_no_iter
=
emitter
.
createCall
(
info
.
unw_info
,
g
.
funcs
.
getiterHelper
,
var
->
getValue
());
emitter
.
setType
(
value_no_iter
,
RefType
::
OWNED
);
llvm
::
BasicBlock
*
value_no_iter_bb
=
emitter
.
currentBasicBlock
();
emitter
.
getBuilder
()
->
CreateBr
(
bb_join
);
auto
no_iter_terminator
=
emitter
.
getBuilder
()
->
CreateBr
(
bb_join
);
// join
emitter
.
setCurrentBasicBlock
(
bb_join
);
...
...
@@ -422,6 +424,10 @@ public:
phi
->
addIncoming
(
value_has_iter
,
value_has_iter_bb
);
phi
->
addIncoming
(
value_no_iter
,
value_no_iter_bb
);
emitter
.
refConsumed
(
value_has_iter
,
has_iter_terminator
);
emitter
.
refConsumed
(
value_no_iter
,
no_iter_terminator
);
emitter
.
setType
(
phi
,
RefType
::
OWNED
);
return
new
ConcreteCompilerVariable
(
UNKNOWN
,
phi
);
}
...
...
@@ -505,6 +511,7 @@ ConcreteCompilerType* UNKNOWN = new UnknownType();
CompilerVariable
*
UnknownType
::
getattr
(
IREmitter
&
emitter
,
const
OpInfo
&
info
,
ConcreteCompilerVariable
*
var
,
BoxedString
*
attr
,
bool
cls_only
)
{
llvm
::
Constant
*
ptr
=
embedRelocatablePtr
(
attr
,
g
.
llvm_boxedstring_type_ptr
);
emitter
.
setType
(
ptr
,
RefType
::
BORROWED
);
llvm
::
Value
*
rtn_val
=
NULL
;
...
...
@@ -539,6 +546,7 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C
}
else
{
rtn_val
=
emitter
.
createCall2
(
info
.
unw_info
,
llvm_func
,
var
->
getValue
(),
ptr
,
target_exception_style
);
}
emitter
.
setType
(
rtn_val
,
RefType
::
OWNED
);
if
(
target_exception_style
==
CAPI
)
emitter
.
checkAndPropagateCapiException
(
info
.
unw_info
,
rtn_val
,
getNullPtr
(
g
.
llvm_value_type_ptr
));
...
...
@@ -716,7 +724,7 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
std
::
vector
<
llvm
::
Value
*>
other_args
;
other_args
.
push_back
(
var
->
getValue
());
other_args
.
push_back
(
em
bedRelocatablePtr
(
attr
,
g
.
llvm_boxedstring_type_ptr
));
other_args
.
push_back
(
em
itter
.
setType
(
embedRelocatablePtr
(
attr
,
g
.
llvm_boxedstring_type_ptr
),
RefType
::
BORROWED
));
other_args
.
push_back
(
getConstantInt
(
flags
.
asInt
(),
g
.
i64
));
return
_call
(
emitter
,
info
,
func
,
exception_style
,
func_ptr
,
other_args
,
flags
.
argspec
,
args
,
keyword_names
,
UNKNOWN
);
...
...
@@ -1779,7 +1787,8 @@ public:
llvm
::
CallSite
call
=
emitter
.
createCall3
(
info
.
unw_info
,
raise_func
,
embedRelocatablePtr
(
cls
->
tp_name
,
g
.
i8_ptr
),
embedRelocatablePtr
(
attr
->
data
(),
g
.
i8_ptr
),
getConstantInt
(
attr
->
size
(),
g
.
i64
),
exception_style
);
emitter
.
setType
(
embedRelocatablePtr
(
attr
->
data
(),
g
.
i8_ptr
),
RefType
::
BORROWED
),
getConstantInt
(
attr
->
size
(),
g
.
i64
),
exception_style
);
if
(
exception_style
==
CAPI
)
{
emitter
.
checkAndPropagateCapiException
(
info
.
unw_info
,
getNullPtr
(
g
.
llvm_value_type_ptr
),
getNullPtr
(
g
.
llvm_value_type_ptr
));
...
...
src/codegen/irgen/irgenerator.cpp
View file @
e1430c45
...
...
@@ -1108,8 +1108,10 @@ private:
emitter
.
setType
(
r
,
RefType
::
OWNED
);
return
new
ConcreteCompilerVariable
(
UNKNOWN
,
r
);
}
else
{
llvm
::
Value
*
r
=
emitter
.
createCall2
(
unw_info
,
g
.
funcs
.
getGlobal
,
irstate
->
getGlobals
(),
embedRelocatablePtr
(
node
->
id
.
getBox
(),
g
.
llvm_boxedstring_type_ptr
));
llvm
::
Value
*
r
=
emitter
.
createCall2
(
unw_info
,
g
.
funcs
.
getGlobal
,
irstate
->
getGlobals
(),
emitter
.
setType
(
embedRelocatablePtr
(
node
->
id
.
getBox
(),
g
.
llvm_boxedstring_type_ptr
),
RefType
::
BORROWED
));
emitter
.
setType
(
r
,
RefType
::
OWNED
);
return
new
ConcreteCompilerVariable
(
UNKNOWN
,
r
);
}
...
...
@@ -1685,9 +1687,10 @@ private:
module
->
setattr
(
emitter
,
getEmptyOpInfo
(
unw_info
),
name
.
getBox
(),
val
);
}
else
{
auto
converted
=
val
->
makeConverted
(
emitter
,
val
->
getBoxType
());
emitter
.
createCall3
(
unw_info
,
g
.
funcs
.
setGlobal
,
irstate
->
getGlobals
(),
embedRelocatablePtr
(
name
.
getBox
(),
g
.
llvm_boxedstring_type_ptr
),
converted
->
getValue
());
emitter
.
createCall3
(
unw_info
,
g
.
funcs
.
setGlobal
,
irstate
->
getGlobals
(),
emitter
.
setType
(
embedRelocatablePtr
(
name
.
getBox
(),
g
.
llvm_boxedstring_type_ptr
),
RefType
::
BORROWED
),
converted
->
getValue
());
}
}
else
if
(
vst
==
ScopeInfo
::
VarScopeType
::
NAME
)
{
// TODO inefficient
...
...
@@ -1802,8 +1805,9 @@ private:
// We could patchpoint this or try to avoid the overhead, but this should only
// happen when the assertion is actually thrown so I don't think it will be necessary.
static
BoxedString
*
AssertionError_str
=
getStaticString
(
"AssertionError"
);
llvm_args
.
push_back
(
emitter
.
createCall2
(
unw_info
,
g
.
funcs
.
getGlobal
,
irstate
->
getGlobals
(),
embedRelocatablePtr
(
AssertionError_str
,
g
.
llvm_boxedstring_type_ptr
)));
llvm_args
.
push_back
(
emitter
.
createCall2
(
unw_info
,
g
.
funcs
.
getGlobal
,
irstate
->
getGlobals
(),
emitter
.
setType
(
embedRelocatablePtr
(
AssertionError_str
,
g
.
llvm_boxedstring_type_ptr
),
RefType
::
BORROWED
)));
ConcreteCompilerVariable
*
converted_msg
=
NULL
;
if
(
node
->
msg
)
{
...
...
src/codegen/irgen/refcounts.cpp
View file @
e1430c45
...
...
@@ -305,10 +305,12 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
llvm
::
Function
*
f
=
irstate
->
getLLVMFunction
();
RefcountTracker
*
rt
=
irstate
->
getRefcounts
();
fprintf
(
stderr
,
"Before refcounts:
\n
"
);
fprintf
(
stderr
,
"
\033
[35m"
);
dumpPrettyIR
(
f
);
fprintf
(
stderr
,
"
\033
[0m"
);
if
(
VERBOSITY
())
{
fprintf
(
stderr
,
"Before refcounts:
\n
"
);
fprintf
(
stderr
,
"
\033
[35m"
);
dumpPrettyIR
(
f
);
fprintf
(
stderr
,
"
\033
[0m"
);
}
#ifndef NDEBUG
int
num_untracked
=
0
;
...
...
@@ -361,7 +363,7 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
printf
(
"missed a refcounted object: "
);
fflush
(
stdout
);
v
->
dump
();
//
abort();
abort
();
}
};
...
...
@@ -625,11 +627,13 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
addDecrefs
(
op
.
operand
,
op
.
num_refs
,
op
.
insertion_pt
);
}
fprintf
(
stderr
,
"After refcounts:
\n
"
);
fprintf
(
stderr
,
"
\033
[35m"
);
f
->
dump
();
//dumpPrettyIR(f);
fprintf
(
stderr
,
"
\033
[0m"
);
if
(
VERBOSITY
())
{
fprintf
(
stderr
,
"After refcounts:
\n
"
);
fprintf
(
stderr
,
"
\033
[35m"
);
f
->
dump
();
//dumpPrettyIR(f);
fprintf
(
stderr
,
"
\033
[0m"
);
}
}
}
// namespace pyston
src/runtime/objmodel.cpp
View file @
e1430c45
...
...
@@ -1601,6 +1601,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
if
(
rewrite_args
)
{
RewriterVar
*
r_rtn
=
rewrite_args
->
rewriter
->
call
(
false
,
(
void
*
)
boxInstanceMethod
,
r_im_self
,
r_im_func
,
r_im_class
);
r_rtn
->
setType
(
RefType
::
OWNED
);
rewrite_args
->
setReturn
(
r_rtn
,
ReturnConvention
::
HAS_RETURN
);
}
return
boxInstanceMethod
(
im_self
,
im_func
,
im_class
);
...
...
@@ -2568,6 +2569,9 @@ template <ExceptionStyle S> Box* _getattrEntry(Box* obj, BoxedString* attr, void
Box
*
val
;
if
(
rewriter
.
get
())
{
rewriter
->
getArg
(
0
)
->
setType
(
RefType
::
BORROWED
);
rewriter
->
getArg
(
1
)
->
setType
(
RefType
::
BORROWED
);
Location
dest
;
TypeRecorder
*
recorder
=
rewriter
->
getTypeRecorder
();
if
(
recorder
)
...
...
@@ -2824,7 +2828,7 @@ extern "C" void setattr(Box* obj, BoxedString* attr, STOLEN(Box*) attr_val) {
if
(
rewriter
.
get
())
{
rewriter
->
getArg
(
0
)
->
setType
(
RefType
::
BORROWED
);
rewriter
->
getArg
(
1
)
->
setType
(
RefType
::
BORROWED
);
rewriter
->
getArg
(
2
)
->
setType
(
RefType
::
BORROW
ED
);
rewriter
->
getArg
(
2
)
->
setType
(
RefType
::
OWN
ED
);
auto
r_cls
=
rewriter
->
getArg
(
0
)
->
getAttr
(
offsetof
(
Box
,
cls
));
// rewriter->trap();
...
...
@@ -3790,13 +3794,10 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
}
}
if
(
rewrite_args
)
{
// TODO should probably rethink the whole vrefcounting thing here.
// which ones actually need new vrefs?
if
(
num_output_args
>=
3
)
{
RELEASE_ASSERT
(
0
,
"not sure what to do here
\n
"
);
//for (int i = 0; i < num_output_args - 3; i++) {
//rewrite_args->args->getAttr(i * sizeof(Box*))->incref();
//}
for
(
int
i
=
0
;
i
<
num_output_args
-
3
;
i
++
)
{
rewrite_args
->
args
->
getAttr
(
i
*
sizeof
(
Box
*
))
->
setType
(
RefType
::
BORROWED
)
->
refConsumed
();
}
}
}
};
...
...
@@ -3884,7 +3885,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
// We might have trouble if we have more output args than input args,
// such as if we need more space to pass defaults.
if
(
num_output_args
>
3
&&
num_output_args
>
num_passed_args
)
{
assert
(
!
rewrite_args
&&
"check refcounting"
);
int
arg_bytes_required
=
(
num_output_args
-
3
)
*
sizeof
(
Box
*
);
RewriterVar
*
new_args
=
NULL
;
...
...
@@ -4193,9 +4193,11 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
rewrite_args
->
arg3
=
rewrite_args
->
rewriter
->
loadConst
((
intptr_t
)
default_obj
,
Location
::
forArg
(
2
))
->
setType
(
RefType
::
BORROWED
);
else
{
assert
(
0
&&
"check refcounting"
);
rewrite_args
->
args
->
setAttr
((
arg_idx
-
3
)
*
sizeof
(
Box
*
),
rewrite_args
->
rewriter
->
loadConst
((
intptr_t
)
default_obj
));
auto
rvar
=
rewrite_args
->
rewriter
->
loadConst
((
intptr_t
)
default_obj
);
rvar
->
setType
(
RefType
::
BORROWED
);
rewrite_args
->
args
->
setAttr
((
arg_idx
-
3
)
*
sizeof
(
Box
*
),
rvar
);
if
(
default_obj
)
rvar
->
refConsumed
();
}
}
...
...
@@ -4367,6 +4369,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
res
=
createGenerator
(
func
,
arg1
,
arg2
,
arg3
,
oargs
);
if
(
rewrite_args
)
{
assert
(
0
&&
"check refcounting"
);
RewriterVar
*
r_arg1
=
num_output_args
>=
1
?
rewrite_args
->
arg1
:
rewrite_args
->
rewriter
->
loadConst
(
0
);
RewriterVar
*
r_arg2
=
num_output_args
>=
2
?
rewrite_args
->
arg2
:
rewrite_args
->
rewriter
->
loadConst
(
0
);
RewriterVar
*
r_arg3
=
num_output_args
>=
3
?
rewrite_args
->
arg3
:
rewrite_args
->
rewriter
->
loadConst
(
0
);
...
...
@@ -4380,8 +4383,11 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
res
=
callCLFunc
<
S
,
rewritable
>
(
md
,
rewrite_args
,
num_output_args
,
closure
,
NULL
,
func
->
globals
,
arg1
,
arg2
,
arg3
,
oargs
);
}
if
(
rewrite_args
)
{
RELEASE_ASSERT
(
num_output_args
<=
3
,
"figure out vrefs for arg array"
);
if
(
rewrite_args
&&
num_output_args
>
3
)
{
for
(
int
i
=
0
;
i
<
num_output_args
-
3
;
i
++
)
{
rewrite_args
->
args
->
getAttr
(
i
*
sizeof
(
Box
*
))
->
setType
(
RefType
::
OWNED
)
->
setNullable
(
true
);
}
}
return
res
;
...
...
@@ -6145,7 +6151,7 @@ extern "C" Box* createBoxedIterWrapperIfNeeded(Box* o) {
static
BoxedString
*
hasnext_str
=
getStaticString
(
"__hasnext__"
);
if
(
rewriter
.
get
())
{
RewriterVar
*
r_o
=
rewriter
->
getArg
(
0
);
RewriterVar
*
r_o
=
rewriter
->
getArg
(
0
)
->
setType
(
RefType
::
BORROWED
)
;
RewriterVar
*
r_cls
=
r_o
->
getAttr
(
offsetof
(
Box
,
cls
));
GetattrRewriteArgs
rewrite_args
(
rewriter
.
get
(),
r_cls
,
rewriter
->
getReturnDestination
());
Box
*
r
=
typeLookup
(
o
->
cls
,
hasnext_str
,
&
rewrite_args
);
...
...
@@ -6155,10 +6161,11 @@ extern "C" Box* createBoxedIterWrapperIfNeeded(Box* o) {
RewriterVar
*
rtn
=
rewrite_args
.
getReturn
(
ReturnConvention
::
HAS_RETURN
);
rtn
->
addGuard
((
uint64_t
)
r
);
rewriter
->
commitReturning
(
r_o
);
return
o
;
return
incref
(
o
)
;
}
else
/* if (!r) */
{
rewrite_args
.
assertReturnConvention
(
ReturnConvention
::
NO_RETURN
);
RewriterVar
*
var
=
rewriter
.
get
()
->
call
(
true
,
(
void
*
)
createBoxedIterWrapper
,
rewriter
->
getArg
(
0
));
var
->
setType
(
RefType
::
OWNED
);
rewriter
->
commitReturning
(
var
);
return
createBoxedIterWrapper
(
o
);
}
...
...
@@ -6167,7 +6174,7 @@ extern "C" Box* createBoxedIterWrapperIfNeeded(Box* o) {
// assert((typeLookup(o->cls, hasnext_str) == NULL) == (o->cls->tpp_hasnext == object_cls->tpp_hasnext));
if
(
o
->
cls
->
tpp_hasnext
==
object_cls
->
tpp_hasnext
)
return
new
BoxedIterWrapper
(
o
);
return
o
;
return
incref
(
o
)
;
}
extern
"C"
Box
*
getPystonIter
(
Box
*
o
)
{
...
...
src/runtime/types.h
View file @
e1430c45
...
...
@@ -445,9 +445,9 @@ public:
#ifdef DISABLE_INT_FREELIST
return
Box
::
operator
new
(
size
,
int_cls
);
#else
if
(
free_list
==
NULL
)
{
if
(
unlikely
(
free_list
==
NULL
)
)
{
free_list
=
fill_free_list
();
RELEASE_ASSERT
(
free_list
,
""
);
assert
(
free_list
);
}
PyIntObject
*
v
=
free_list
;
...
...
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