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
5c70bb30
Commit
5c70bb30
authored
Aug 27, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #870 from undingen/trampoline
Small improvements to reduce the size of rewrites
parents
15098268
4f745cab
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
53 additions
and
32 deletions
+53
-32
src/asm_writing/assembler.cpp
src/asm_writing/assembler.cpp
+11
-0
src/asm_writing/assembler.h
src/asm_writing/assembler.h
+2
-0
src/asm_writing/rewriter.cpp
src/asm_writing/rewriter.cpp
+32
-24
src/asm_writing/rewriter.h
src/asm_writing/rewriter.h
+5
-5
src/codegen/baseline_jit.cpp
src/codegen/baseline_jit.cpp
+2
-2
src/codegen/baseline_jit.h
src/codegen/baseline_jit.h
+1
-1
No files found.
src/asm_writing/assembler.cpp
View file @
5c70bb30
...
...
@@ -300,6 +300,17 @@ void Assembler::movslq(Indirect src, Register dest) {
mov_generic
(
src
,
dest
,
MovType
::
SLQ
);
}
void
Assembler
::
clear_reg
(
Register
reg
)
{
int
reg_idx
=
reg
.
regnum
;
// we don't need to generate a REX_W because 32bit instructions will clear the upper 32bits.
if
(
reg_idx
>=
8
)
{
emitRex
(
REX_R
|
REX_B
);
reg_idx
-=
8
;
}
emitByte
(
0x31
);
emitModRM
(
0b11
,
reg_idx
,
reg_idx
);
}
void
Assembler
::
mov_generic
(
Indirect
src
,
Register
dest
,
MovType
type
)
{
int
rex
;
switch
(
type
)
{
...
...
src/asm_writing/assembler.h
View file @
5c70bb30
...
...
@@ -144,6 +144,8 @@ public:
void
movswq
(
Indirect
scr
,
Register
dest
);
void
movslq
(
Indirect
scr
,
Register
dest
);
void
clear_reg
(
Register
reg
);
// = xor reg, reg
void
mov_generic
(
Indirect
src
,
Register
dest
,
MovType
type
);
void
push
(
Register
reg
);
...
...
src/asm_writing/rewriter.cpp
View file @
5c70bb30
...
...
@@ -206,6 +206,11 @@ assembler::Register Rewriter::ConstLoader::findConst(uint64_t val, bool& found_v
void
Rewriter
::
ConstLoader
::
loadConstIntoReg
(
uint64_t
val
,
assembler
::
Register
dst_reg
)
{
assert
(
rewriter
->
phase_emitting
);
if
(
val
==
0
)
{
rewriter
->
assembler
->
clear_reg
(
dst_reg
);
return
;
}
if
(
tryRegRegMove
(
val
,
dst_reg
))
return
;
...
...
@@ -215,22 +220,6 @@ void Rewriter::ConstLoader::loadConstIntoReg(uint64_t val, assembler::Register d
moveImmediate
(
val
,
dst_reg
);
}
assembler
::
Register
Rewriter
::
ConstLoader
::
loadConst
(
uint64_t
val
,
Location
otherThan
)
{
assert
(
rewriter
->
phase_emitting
);
bool
found_value
=
false
;
assembler
::
Register
/*reg = findConst(val, found_value);
if (found_value)
return reg;*/
reg
=
rewriter
->
allocReg
(
Location
::
any
(),
otherThan
);
if
(
tryLea
(
val
,
reg
))
return
reg
;
moveImmediate
(
val
,
reg
);
return
reg
;
}
void
Rewriter
::
restoreArgs
()
{
ASSERT
(
!
done_guarding
,
"this will probably work but why are we calling this at this time"
);
...
...
@@ -284,6 +273,23 @@ void RewriterVar::addGuard(uint64_t val) {
rewriter
->
addAction
([
=
]()
{
rewriter
->
_addGuard
(
this
,
val_var
);
},
{
this
,
val_var
},
ActionType
::
GUARD
);
}
void
Rewriter
::
_slowpathJump
(
bool
condition_eq
)
{
// If a jump offset is larger then 0x80 the instruction encoding requires 6bytes instead of 2bytes.
// This adds up quickly, thats why we will try to find another jump to the slowpath with the same condition with a
// smaller offset and jump to it / use it as a trampoline.
// The benchmark show that this increases the performance slightly even though it introduces additional jumps.
int
&
last_jmp_offset
=
condition_eq
?
offset_eq_jmp_slowpath
:
offset_ne_jmp_slowpath
;
auto
condition
=
condition_eq
?
assembler
::
COND_EQUAL
:
assembler
::
COND_NOT_EQUAL
;
assert
(
assembler
->
bytesWritten
()
+
assembler
->
bytesLeft
()
==
rewrite
->
getSlotSize
());
if
(
last_jmp_offset
!=
-
1
&&
assembler
->
bytesLeft
()
>=
0x80
&&
assembler
->
bytesWritten
()
-
last_jmp_offset
<
0x80
)
{
assembler
->
jmp_cond
(
assembler
::
JumpDestination
::
fromStart
(
last_jmp_offset
),
condition
);
}
else
{
last_jmp_offset
=
assembler
->
bytesWritten
();
assembler
->
jmp_cond
(
assembler
::
JumpDestination
::
fromStart
(
rewrite
->
getSlotSize
()),
condition
);
}
}
void
Rewriter
::
_addGuard
(
RewriterVar
*
var
,
RewriterVar
*
val_constant
)
{
assembler
->
comment
(
"_addGuard"
);
...
...
@@ -300,7 +306,7 @@ void Rewriter::_addGuard(RewriterVar* var, RewriterVar* val_constant) {
restoreArgs
();
// can only do movs, doesn't affect flags, so it's safe
assertArgsInPlace
();
assembler
->
jne
(
assembler
::
JumpDestination
::
fromStart
(
rewrite
->
getSlotSize
())
);
_slowpathJump
(
false
/*= not equal jmp */
);
var
->
bumpUse
();
val_constant
->
bumpUse
();
...
...
@@ -331,7 +337,7 @@ void Rewriter::_addGuardNotEq(RewriterVar* var, RewriterVar* val_constant) {
restoreArgs
();
// can only do movs, doesn't affect flags, so it's safe
assertArgsInPlace
();
assembler
->
je
(
assembler
::
JumpDestination
::
fromStart
(
rewrite
->
getSlotSize
())
);
_slowpathJump
(
true
/*= equal jmp */
);
var
->
bumpUse
();
val_constant
->
bumpUse
();
...
...
@@ -381,10 +387,7 @@ void Rewriter::_addAttrGuard(RewriterVar* var, int offset, RewriterVar* val_cons
restoreArgs
();
// can only do movs, doesn't affect flags, so it's safe
assertArgsInPlace
();
if
(
negate
)
assembler
->
je
(
assembler
::
JumpDestination
::
fromStart
(
rewrite
->
getSlotSize
()));
else
assembler
->
jne
(
assembler
::
JumpDestination
::
fromStart
(
rewrite
->
getSlotSize
()));
_slowpathJump
(
negate
);
var
->
bumpUse
();
val_constant
->
bumpUse
();
...
...
@@ -894,6 +897,9 @@ void Rewriter::_setupCall(bool has_side_effects, llvm::ArrayRef<RewriterVar*> ar
assembler
::
Immediate
imm
=
var
->
tryGetAsImmediate
(
&
is_immediate
);
if
(
is_immediate
)
{
if
(
imm
.
val
==
0
)
assembler
->
clear_reg
(
r
);
else
assembler
->
mov
(
imm
,
r
);
addLocationToVar
(
var
,
l
);
}
else
{
...
...
@@ -1813,8 +1819,10 @@ Rewriter::Rewriter(std::unique_ptr<ICSlotRewrite> rewrite, int num_args, const L
failed
(
false
),
added_changing_action
(
false
),
marked_inside_ic
(
false
),
done_guarding
(
false
),
last_guard_action
(
-
1
),
done_guarding
(
false
)
{
offset_eq_jmp_slowpath
(
-
1
),
offset_ne_jmp_slowpath
(
-
1
)
{
initPhaseCollecting
();
finished
=
false
;
...
...
src/asm_writing/rewriter.h
View file @
5c70bb30
...
...
@@ -379,9 +379,6 @@ protected:
// Loads the constant into the specified register
void
loadConstIntoReg
(
uint64_t
val
,
assembler
::
Register
reg
);
// Loads the constant into any register or if already in a register just return it
assembler
::
Register
loadConst
(
uint64_t
val
,
Location
otherThan
=
Location
::
any
());
llvm
::
SmallVector
<
std
::
pair
<
uint64_t
,
RewriterVar
*>
,
16
>
consts
;
};
...
...
@@ -444,14 +441,16 @@ protected:
bool
added_changing_action
;
bool
marked_inside_ic
;
int
last_guard_action
;
bool
done_guarding
;
bool
isDoneGuarding
()
{
assertPhaseEmitting
();
return
done_guarding
;
}
int
last_guard_action
;
int
offset_eq_jmp_slowpath
;
int
offset_ne_jmp_slowpath
;
// Move the original IC args back into their original registers:
void
restoreArgs
();
// Assert that our original args are correctly placed in case we need to
...
...
@@ -482,6 +481,7 @@ protected:
bool
finishAssembly
(
int
continue_offset
)
override
;
void
_slowpathJump
(
bool
condition_eq
);
void
_trap
();
void
_loadConst
(
RewriterVar
*
result
,
int64_t
val
);
void
_setupCall
(
bool
has_side_effects
,
llvm
::
ArrayRef
<
RewriterVar
*>
args
,
llvm
::
ArrayRef
<
RewriterVar
*>
args_xmm
);
...
...
src/codegen/baseline_jit.cpp
View file @
5c70bb30
...
...
@@ -810,7 +810,7 @@ void JitFragmentWriter::_emitOSRPoint(RewriterVar* result, RewriterVar* node_var
assembler
->
test
(
result_reg
,
result_reg
);
{
assembler
::
ForwardJump
je
(
*
assembler
,
assembler
::
COND_EQUAL
);
assembler
->
mov
(
assembler
::
Immediate
(
0ul
),
assembler
::
RAX
);
// TODO: use xor
assembler
->
clear_reg
(
assembler
::
RAX
);
assembler
->
add
(
assembler
::
Immediate
(
JitCodeBlock
::
sp_adjustment
),
assembler
::
RSP
);
assembler
->
pop
(
assembler
::
R12
);
assembler
->
pop
(
assembler
::
R14
);
...
...
@@ -904,7 +904,7 @@ void JitFragmentWriter::_emitRecordType(RewriterVar* type_recorder_var, Rewriter
void
JitFragmentWriter
::
_emitReturn
(
RewriterVar
*
return_val
)
{
return_val
->
getInReg
(
assembler
::
RDX
,
true
);
assembler
->
mov
(
assembler
::
Immediate
(
0ul
),
assembler
::
RAX
);
// TODO: use xor
assembler
->
clear_reg
(
assembler
::
RAX
);
assembler
->
add
(
assembler
::
Immediate
(
JitCodeBlock
::
sp_adjustment
),
assembler
::
RSP
);
assembler
->
pop
(
assembler
::
R12
);
assembler
->
pop
(
assembler
::
R14
);
...
...
src/codegen/baseline_jit.h
View file @
5c70bb30
...
...
@@ -117,7 +117,7 @@ class JitFragmentWriter;
// second_JitFragment:
// ...
// ; this shows how a AST_Return looks like
//
mov $0,%rax
; rax contains the next block to interpret.
//
xor %eax,%eax
; rax contains the next block to interpret.
// in this case 0 which means we are finished
// movabs $0x1270014108,%rdx ; rdx must contain the Box* value to return
// add $0x118,%rsp ; restore stack pointer
...
...
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