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
351b3060
Commit
351b3060
authored
Sep 13, 2014
by
Travis Hance
Committed by
Travis Hance
Oct 29, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
member descriptor ics
parent
e36e88e5
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
154 additions
and
32 deletions
+154
-32
src/asm_writing/assembler.cpp
src/asm_writing/assembler.cpp
+36
-5
src/asm_writing/assembler.h
src/asm_writing/assembler.h
+8
-1
src/asm_writing/rewriter.cpp
src/asm_writing/rewriter.cpp
+20
-6
src/asm_writing/rewriter.h
src/asm_writing/rewriter.h
+5
-2
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+54
-11
test/tests/class_noctor.py
test/tests/class_noctor.py
+0
-3
test/tests/member_descriptor_ics.py
test/tests/member_descriptor_ics.py
+30
-0
test/tests/object_new_arguments.py
test/tests/object_new_arguments.py
+0
-3
tools/tester.py
tools/tester.py
+1
-1
No files found.
src/asm_writing/assembler.cpp
View file @
351b3060
...
...
@@ -122,7 +122,9 @@ void Assembler::emitInt(int64_t n, int bytes) {
}
void
Assembler
::
emitRex
(
uint8_t
rex
)
{
if
(
rex
!=
0
)
{
emitByte
(
rex
|
0x40
);
}
}
void
Assembler
::
emitModRM
(
uint8_t
mod
,
uint8_t
reg
,
uint8_t
rm
)
{
...
...
@@ -261,8 +263,20 @@ void Assembler::mov(Register src, Indirect dest) {
}
}
void
Assembler
::
mov
(
Indirect
src
,
Register
dest
)
{
int
rex
=
REX_W
;
void
Assembler
::
mov
(
Indirect
src
,
Register
dest
,
MovType
type
)
{
int
rex
;
switch
(
type
)
{
case
MovType
:
:
Q
:
rex
=
REX_W
;
break
;
case
MovType
:
:
L
:
case
MovType
:
:
B
:
case
MovType
:
:
ZBL
:
rex
=
0
;
break
;
default:
RELEASE_ASSERT
(
false
,
"unrecognized MovType"
);
}
int
src_idx
=
src
.
base
.
regnum
;
int
dest_idx
=
dest
.
regnum
;
...
...
@@ -276,8 +290,25 @@ void Assembler::mov(Indirect src, Register dest) {
dest_idx
-=
8
;
}
if
(
rex
)
emitRex
(
rex
);
emitByte
(
0x8b
);
// opcode
// opcode
switch
(
type
)
{
case
MovType
:
:
Q
:
case
MovType
:
:
L
:
emitByte
(
0x8b
);
break
;
case
MovType
:
:
B
:
emitByte
(
0x8a
);
break
;
case
MovType
:
:
ZBL
:
emitByte
(
0x0f
);
emitByte
(
0xb6
);
break
;
default:
RELEASE_ASSERT
(
false
,
"unrecognized MovType"
);
}
bool
needssib
=
(
src_idx
==
0b100
);
...
...
src/asm_writing/assembler.h
View file @
351b3060
...
...
@@ -48,6 +48,13 @@ enum ConditionCode {
COND_GREATER
=
0xF
,
// ZF=0 && SF==OF: NLE/G
};
enum
class
MovType
{
Q
,
L
,
B
,
ZBL
,
};
class
Assembler
{
private:
uint8_t
*
const
start_addr
,
*
const
end_addr
;
...
...
@@ -80,7 +87,7 @@ public:
void
movq
(
Immediate
imm
,
Indirect
dest
);
void
mov
(
Register
src
,
Register
dest
);
void
mov
(
Register
src
,
Indirect
dest
);
void
mov
(
Indirect
src
,
Register
dest
);
void
mov
(
Indirect
src
,
Register
dest
,
MovType
type
=
MovType
::
Q
);
void
movsd
(
XMMRegister
src
,
XMMRegister
dest
);
void
movsd
(
XMMRegister
src
,
Indirect
dest
);
void
movsd
(
Indirect
src
,
XMMRegister
dest
);
...
...
src/asm_writing/rewriter.cpp
View file @
351b3060
...
...
@@ -191,7 +191,7 @@ void RewriterVarUsage::addAttrGuard(int offset, uint64_t val, bool negate) {
assembler
->
jne
(
assembler
::
JumpDestination
::
fromStart
(
rewriter
->
rewrite
->
getSlotSize
()));
}
RewriterVarUsage
RewriterVarUsage
::
getAttr
(
int
offset
,
KillFlag
kill
,
Location
dest
)
{
RewriterVarUsage
RewriterVarUsage
::
getAttr
(
int
offset
,
KillFlag
kill
,
Location
dest
,
assembler
::
MovType
type
)
{
assertValid
();
// Save these, since if we kill this register the var might disappear:
...
...
@@ -202,10 +202,18 @@ RewriterVarUsage RewriterVarUsage::getAttr(int offset, KillFlag kill, Location d
setDoneUsing
();
}
if
(
dest
.
type
==
Location
::
XMMRegister
)
{
assert
(
rewriter
->
vars_by_location
.
count
(
dest
)
==
0
);
assembler
::
XMMRegister
newvar_reg
=
dest
.
asXMMRegister
();
RewriterVarUsage
newvar
=
rewriter
->
createNewVar
(
dest
);
rewriter
->
assembler
->
movsd
(
assembler
::
Indirect
(
this_reg
,
offset
),
newvar_reg
);
return
std
::
move
(
newvar
);
}
else
{
assembler
::
Register
newvar_reg
=
rewriter
->
allocReg
(
dest
);
RewriterVarUsage
newvar
=
rewriter
->
createNewVar
(
newvar_reg
);
rewriter
->
assembler
->
mov
(
assembler
::
Indirect
(
this_reg
,
offset
),
newvar_reg
);
rewriter
->
assembler
->
mov
(
assembler
::
Indirect
(
this_reg
,
offset
),
newvar_reg
,
type
);
return
std
::
move
(
newvar
);
}
}
RewriterVarUsage
RewriterVarUsage
::
cmp
(
AST_TYPE
::
AST_TYPE
cmp_type
,
RewriterVarUsage
other
,
Location
dest
)
{
...
...
@@ -533,7 +541,8 @@ static const Location caller_save_registers[]{
assembler
::
XMM11
,
assembler
::
XMM12
,
assembler
::
XMM13
,
assembler
::
XMM14
,
assembler
::
XMM15
,
};
RewriterVarUsage
Rewriter
::
call
(
bool
can_call_into_python
,
void
*
func_addr
,
std
::
vector
<
RewriterVarUsage
>
args
)
{
RewriterVarUsage
Rewriter
::
call
(
bool
can_call_into_python
,
void
*
func_addr
,
std
::
vector
<
RewriterVarUsage
>
args
,
std
::
vector
<
RewriterVarUsage
>
args_xmm
)
{
// TODO figure out why this is here -- what needs to be done differently
// if can_call_into_python is true?
// assert(!can_call_into_python);
...
...
@@ -577,6 +586,11 @@ RewriterVarUsage Rewriter::call(bool can_call_into_python, void* func_addr, std:
assert
(
var
->
isInLocation
(
Location
::
forArg
(
i
)));
}
for
(
int
i
=
0
;
i
<
args_xmm
.
size
();
i
++
)
{
Location
l
((
assembler
::
XMMRegister
(
i
)));
assert
(
args_xmm
[
i
].
var
->
isInLocation
(
l
));
}
#ifndef NDEBUG
for
(
int
i
=
0
;
i
<
args
.
size
();
i
++
)
{
RewriterVar
*
var
=
args
[
i
].
var
;
...
...
src/asm_writing/rewriter.h
View file @
351b3060
...
...
@@ -93,6 +93,7 @@ public:
static
constexpr
Location
any
()
{
return
Location
(
AnyReg
,
0
);
}
static
constexpr
Location
none
()
{
return
Location
(
None
,
0
);
}
static
Location
forArg
(
int
argnum
);
static
Location
forXMMArg
(
int
argnum
);
bool
operator
==
(
const
Location
rhs
)
const
{
return
this
->
asInt
()
==
rhs
.
asInt
();
}
...
...
@@ -160,7 +161,8 @@ public:
void
addGuard
(
uint64_t
val
);
void
addGuardNotEq
(
uint64_t
val
);
void
addAttrGuard
(
int
offset
,
uint64_t
val
,
bool
negate
=
false
);
RewriterVarUsage
getAttr
(
int
offset
,
KillFlag
kill
,
Location
loc
=
Location
::
any
());
RewriterVarUsage
getAttr
(
int
offset
,
KillFlag
kill
,
Location
loc
=
Location
::
any
(),
assembler
::
MovType
type
=
assembler
::
MovType
::
Q
);
void
setAttr
(
int
offset
,
RewriterVarUsage
other
);
RewriterVarUsage
cmp
(
AST_TYPE
::
AST_TYPE
cmp_type
,
RewriterVarUsage
other
,
Location
loc
=
Location
::
any
());
RewriterVarUsage
toBool
(
KillFlag
kill
,
Location
loc
=
Location
::
any
());
...
...
@@ -292,7 +294,8 @@ public:
void
trap
();
RewriterVarUsage
loadConst
(
int64_t
val
,
Location
loc
=
Location
::
any
());
RewriterVarUsage
call
(
bool
can_call_into_python
,
void
*
func_addr
,
std
::
vector
<
RewriterVarUsage
>
args
);
RewriterVarUsage
call
(
bool
can_call_into_python
,
void
*
func_addr
,
std
::
vector
<
RewriterVarUsage
>
args
,
std
::
vector
<
RewriterVarUsage
>
args_xmm
=
std
::
vector
<
RewriterVarUsage
>
());
RewriterVarUsage
call
(
bool
can_call_into_python
,
void
*
func_addr
,
RewriterVarUsage
arg0
);
RewriterVarUsage
call
(
bool
can_call_into_python
,
void
*
func_addr
,
RewriterVarUsage
arg0
,
RewriterVarUsage
arg1
);
RewriterVarUsage
allocate
(
int
n
);
...
...
src/runtime/objmodel.cpp
View file @
351b3060
...
...
@@ -881,10 +881,20 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box* o
RewriterVarUsage
&
r_descr
,
bool
for_call
,
bool
*
should_bind_out
)
{
// Special case: data descriptor: member descriptor
if
(
descr
->
cls
==
member_cls
)
{
static
StatCounter
slowpath
(
"slowpath_member_descriptor_get"
);
slowpath
.
log
();
BoxedMemberDescriptor
*
member_desc
=
static_cast
<
BoxedMemberDescriptor
*>
(
descr
);
// TODO should also have logic to raise a type error if type of obj is wrong
if
(
rewrite_args
)
{
// TODO we should use this an index in the lookup rather than hardcoding
// the value and guarding on it be the same.
RewriterVarUsage
r_offset
=
r_descr
.
getAttr
(
offsetof
(
BoxedMemberDescriptor
,
offset
),
RewriterVarUsage
::
KillFlag
::
NoKill
,
Location
::
any
());
r_offset
.
addGuard
(
member_desc
->
offset
);
r_offset
.
setDoneUsing
();
if
(
rewrite_args
->
call_done_guarding
)
rewrite_args
->
rewriter
->
setDoneGuarding
();
r_descr
.
setDoneUsing
();
...
...
@@ -892,37 +902,70 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box* o
switch
(
member_desc
->
type
)
{
case
BoxedMemberDescriptor
:
:
OBJECT
:
{
assert
(
member_desc
->
offset
%
sizeof
(
Box
*
)
==
0
);
Box
*
rtn
=
reinterpret_cast
<
Box
**>
(
obj
)[
member_desc
->
offset
/
sizeof
(
Box
*
)];
RELEASE_ASSERT
(
rtn
,
""
);
if
(
rewrite_args
)
{
rewrite_args
->
out_rtn
=
rewrite_args
->
obj
.
getAttr
(
member_desc
->
offset
,
RewriterVarUsage
::
KillFlag
::
Kill
,
rewrite_args
->
destination
);
rewrite_args
->
out_success
=
true
;
}
Box
*
rtn
=
*
reinterpret_cast
<
Box
**>
((
char
*
)
obj
+
member_desc
->
offset
);
RELEASE_ASSERT
(
rtn
,
""
);
return
rtn
;
}
case
BoxedMemberDescriptor
:
:
BYTE
:
{
// TODO rewriter stuff for these other cases as well
rewrite_args
=
NULL
;
if
(
rewrite_args
)
{
RewriterVarUsage
r_unboxed_val
=
rewrite_args
->
obj
.
getAttr
(
member_desc
->
offset
,
RewriterVarUsage
::
KillFlag
::
Kill
,
Location
::
forArg
(
0
),
assembler
::
MovType
::
ZBL
);
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
false
,
(
void
*
)
boxInt
,
std
::
move
(
r_unboxed_val
));
rewrite_args
->
out_success
=
true
;
}
int8_t
rtn
=
reinterpret_cast
<
int8_t
*>
(
obj
)[
member_desc
->
offset
];
return
boxInt
(
rtn
);
}
case
BoxedMemberDescriptor
:
:
BOOL
:
{
rewrite_args
=
NULL
;
if
(
rewrite_args
)
{
RewriterVarUsage
r_unboxed_val
=
rewrite_args
->
obj
.
getAttr
(
member_desc
->
offset
,
RewriterVarUsage
::
KillFlag
::
Kill
,
Location
::
forArg
(
0
),
assembler
::
MovType
::
B
);
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
false
,
(
void
*
)
boxBool
,
std
::
move
(
r_unboxed_val
));
rewrite_args
->
out_success
=
true
;
}
bool
rtn
=
reinterpret_cast
<
bool
*>
(
obj
)[
member_desc
->
offset
];
return
boxBool
(
rtn
);
}
case
BoxedMemberDescriptor
:
:
INT
:
{
rewrite_args
=
NULL
;
int
rtn
=
reinterpret_cast
<
int
*>
(
obj
)[
member_desc
->
offset
/
sizeof
(
int
)];
// rewrite_args = NULL;
if
(
rewrite_args
)
{
rewrite_args
->
rewriter
->
trap
();
RewriterVarUsage
r_unboxed_val
=
rewrite_args
->
obj
.
getAttr
(
member_desc
->
offset
,
RewriterVarUsage
::
KillFlag
::
Kill
,
Location
::
forArg
(
0
),
assembler
::
MovType
::
L
);
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
false
,
(
void
*
)
boxInt
,
std
::
move
(
r_unboxed_val
));
rewrite_args
->
out_success
=
true
;
}
int
rtn
=
*
reinterpret_cast
<
int
*>
((
char
*
)
obj
+
member_desc
->
offset
);
return
boxInt
(
rtn
);
}
case
BoxedMemberDescriptor
:
:
FLOAT
:
{
rewrite_args
=
NULL
;
double
rtn
=
reinterpret_cast
<
double
*>
(
obj
)[
member_desc
->
offset
/
sizeof
(
double
)];
if
(
rewrite_args
)
{
RewriterVarUsage
r_unboxed_val
=
rewrite_args
->
obj
.
getAttr
(
member_desc
->
offset
,
RewriterVarUsage
::
KillFlag
::
Kill
,
assembler
::
XMM0
);
std
::
vector
<
RewriterVarUsage
>
normal_args
;
std
::
vector
<
RewriterVarUsage
>
float_args
;
float_args
.
push_back
(
std
::
move
(
r_unboxed_val
));
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
false
,
(
void
*
)
boxFloat
,
std
::
move
(
normal_args
),
std
::
move
(
float_args
));
rewrite_args
->
out_success
=
true
;
}
double
rtn
=
*
reinterpret_cast
<
double
*>
((
char
*
)
obj
+
member_desc
->
offset
);
return
boxFloat
(
rtn
);
}
default:
...
...
test/tests/class_noctor.py
View file @
351b3060
# skip-if: sys.version_info.micro >= 4
# - Error message changed in 2.7.4
# Regression test:
# If the init function doesn't exist, shouldn't just silently ignore any args
# that got passed
...
...
test/tests/member_descriptor_ics.py
0 → 100644
View file @
351b3060
# run_args: -n
# statcheck: noninit_count('slowpath_member_descriptor_get') <= 50
f
=
open
(
"/dev/null"
)
def
go
():
# object
s
=
slice
(
i
,
1.0
,
"abc"
)
print
s
.
start
print
s
.
stop
print
s
.
step
# byte
# TODO
# using softspace works for this test as long as we implement softspace as
# a member descriptor but it should actually a getset_descriptor
# in addition to fixing that, we should replace it in this test with a legit
# member descriptor
print
f
.
softspace
# TODO figure out what uses BOOL and test that
# TODO figure out what uses INT and test that
# float
c
=
1j
+
i
print
c
.
real
print
c
.
imag
for
i
in
xrange
(
1000
):
go
();
test/tests/object_new_arguments.py
View file @
351b3060
# skip-if: sys.version_info.micro >= 4
# - Error message changed in 2.7.4
# object.__new__ doesn't complain if __init__ is overridden:
class
C1
(
object
):
...
...
tools/tester.py
View file @
351b3060
...
...
@@ -35,7 +35,7 @@ IMAGE = "pyston_dbg"
KEEP_GOING
=
False
FN_JUST_SIZE
=
20
EXTRA_JIT_ARGS
=
[]
TIME_LIMIT
=
3
TIME_LIMIT
=
4
# For fun, can test pypy.
# Tough because the tester will check to see if the error messages are exactly the
...
...
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