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
74fce7a4
Commit
74fce7a4
authored
Sep 04, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #885 from rudi-c/compileconstants
Scan constants written into compiled code.
parents
1c9ebd80
ea496d13
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
164 additions
and
6 deletions
+164
-6
src/asm_writing/icinfo.cpp
src/asm_writing/icinfo.cpp
+49
-4
src/asm_writing/icinfo.h
src/asm_writing/icinfo.h
+12
-1
src/asm_writing/rewriter.cpp
src/asm_writing/rewriter.cpp
+18
-1
src/asm_writing/rewriter.h
src/asm_writing/rewriter.h
+1
-0
src/codegen/baseline_jit.cpp
src/codegen/baseline_jit.cpp
+9
-0
src/codegen/irgen.cpp
src/codegen/irgen.cpp
+1
-0
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+21
-0
src/codegen/irgen/util.cpp
src/codegen/irgen/util.cpp
+24
-0
src/codegen/irgen/util.h
src/codegen/irgen/util.h
+8
-0
src/core/types.h
src/core/types.h
+5
-0
src/gc/collector.cpp
src/gc/collector.cpp
+8
-0
src/gc/gc.h
src/gc/gc.h
+8
-0
No files found.
src/asm_writing/icinfo.cpp
View file @
74fce7a4
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
#include <cstring>
#include <cstring>
#include <memory>
#include <memory>
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/Memory.h"
#include "asm_writing/assembler.h"
#include "asm_writing/assembler.h"
...
@@ -25,6 +26,9 @@
...
@@ -25,6 +26,9 @@
#include "core/common.h"
#include "core/common.h"
#include "core/options.h"
#include "core/options.h"
#include "core/types.h"
#include "core/types.h"
#include "gc/gc.h"
#include "gc/heap.h"
#include "runtime/types.h"
namespace
pyston
{
namespace
pyston
{
...
@@ -49,8 +53,6 @@ void ICInvalidator::invalidateAll() {
...
@@ -49,8 +53,6 @@ void ICInvalidator::invalidateAll() {
dependents
.
clear
();
dependents
.
clear
();
}
}
void
ICSlotInfo
::
clear
()
{
void
ICSlotInfo
::
clear
()
{
ic
->
clear
(
this
);
ic
->
clear
(
this
);
}
}
...
@@ -82,7 +84,7 @@ uint8_t* ICSlotRewrite::getSlotStart() {
...
@@ -82,7 +84,7 @@ uint8_t* ICSlotRewrite::getSlotStart() {
return
(
uint8_t
*
)
ic
->
start_addr
+
ic_entry
->
idx
*
ic
->
getSlotSize
();
return
(
uint8_t
*
)
ic
->
start_addr
+
ic_entry
->
idx
*
ic
->
getSlotSize
();
}
}
void
ICSlotRewrite
::
commit
(
CommitHook
*
hook
)
{
void
ICSlotRewrite
::
commit
(
CommitHook
*
hook
,
std
::
vector
<
void
*>
gc_references
)
{
bool
still_valid
=
true
;
bool
still_valid
=
true
;
for
(
int
i
=
0
;
i
<
dependencies
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
dependencies
.
size
();
i
++
)
{
int
orig_version
=
dependencies
[
i
].
second
;
int
orig_version
=
dependencies
[
i
].
second
;
...
@@ -118,6 +120,8 @@ void ICSlotRewrite::commit(CommitHook* hook) {
...
@@ -118,6 +120,8 @@ void ICSlotRewrite::commit(CommitHook* hook) {
// if (VERBOSITY()) printf("Commiting to %p-%p\n", start, start + ic->slot_size);
// if (VERBOSITY()) printf("Commiting to %p-%p\n", start, start + ic->slot_size);
memcpy
(
slot_start
,
buf
,
ic
->
getSlotSize
());
memcpy
(
slot_start
,
buf
,
ic
->
getSlotSize
());
ic_entry
->
gc_references
=
std
::
move
(
gc_references
);
ic
->
times_rewritten
++
;
ic
->
times_rewritten
++
;
if
(
ic
->
times_rewritten
==
IC_MEGAMORPHIC_THRESHOLD
)
{
if
(
ic
->
times_rewritten
==
IC_MEGAMORPHIC_THRESHOLD
)
{
...
@@ -187,6 +191,25 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(const char* debug_name) {
...
@@ -187,6 +191,25 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(const char* debug_name) {
return
NULL
;
return
NULL
;
}
}
// Keep track of all ICInfo(s) that we create because they contain pointers to Pyston heap objects
// that we have written into the generated code and we may need to scan those.
static
llvm
::
DenseSet
<
ICInfo
*>
ics_list
;
static
llvm
::
DenseMap
<
void
*
,
ICInfo
*>
ics_by_return_addr
;
void
registerGCTrackedICInfo
(
ICInfo
*
ic
)
{
#if MOVING_GC
assert
(
ics_list
.
count
(
ic
)
==
0
);
ics_list
.
insert
(
ic
);
#endif
}
void
deregisterGCTrackedICInfo
(
ICInfo
*
ic
)
{
#if MOVING_GC
assert
(
ics_list
.
count
(
ic
)
==
1
);
ics_list
.
erase
(
ic
);
#endif
}
ICInfo
::
ICInfo
(
void
*
start_addr
,
void
*
slowpath_rtn_addr
,
void
*
continue_addr
,
StackInfo
stack_info
,
int
num_slots
,
ICInfo
::
ICInfo
(
void
*
start_addr
,
void
*
slowpath_rtn_addr
,
void
*
continue_addr
,
StackInfo
stack_info
,
int
num_slots
,
int
slot_size
,
llvm
::
CallingConv
::
ID
calling_conv
,
LiveOutSet
_live_outs
,
int
slot_size
,
llvm
::
CallingConv
::
ID
calling_conv
,
LiveOutSet
_live_outs
,
assembler
::
GenericRegister
return_register
,
TypeRecorder
*
type_recorder
)
assembler
::
GenericRegister
return_register
,
TypeRecorder
*
type_recorder
)
...
@@ -207,9 +230,18 @@ ICInfo::ICInfo(void* start_addr, void* slowpath_rtn_addr, void* continue_addr, S
...
@@ -207,9 +230,18 @@ ICInfo::ICInfo(void* start_addr, void* slowpath_rtn_addr, void* continue_addr, S
for
(
int
i
=
0
;
i
<
num_slots
;
i
++
)
{
for
(
int
i
=
0
;
i
<
num_slots
;
i
++
)
{
slots
.
emplace_back
(
this
,
i
);
slots
.
emplace_back
(
this
,
i
);
}
}
#if MOVING_GC
assert
(
ics_list
.
count
(
this
)
==
0
);
#endif
}
ICInfo
::~
ICInfo
()
{
#if MOVING_GC
assert
(
ics_list
.
count
(
this
)
==
0
);
#endif
}
}
static
llvm
::
DenseMap
<
void
*
,
ICInfo
*>
ics_by_return_addr
;
std
::
unique_ptr
<
ICInfo
>
registerCompiledPatchpoint
(
uint8_t
*
start_addr
,
uint8_t
*
slowpath_start_addr
,
std
::
unique_ptr
<
ICInfo
>
registerCompiledPatchpoint
(
uint8_t
*
start_addr
,
uint8_t
*
slowpath_start_addr
,
uint8_t
*
continue_addr
,
uint8_t
*
slowpath_rtn_addr
,
uint8_t
*
continue_addr
,
uint8_t
*
slowpath_rtn_addr
,
const
ICSetupInfo
*
ic
,
StackInfo
stack_info
,
LiveOutSet
live_outs
)
{
const
ICSetupInfo
*
ic
,
StackInfo
stack_info
,
LiveOutSet
live_outs
)
{
...
@@ -251,14 +283,19 @@ std::unique_ptr<ICInfo> registerCompiledPatchpoint(uint8_t* start_addr, uint8_t*
...
@@ -251,14 +283,19 @@ std::unique_ptr<ICInfo> registerCompiledPatchpoint(uint8_t* start_addr, uint8_t*
ICInfo
*
icinfo
=
new
ICInfo
(
start_addr
,
slowpath_rtn_addr
,
continue_addr
,
stack_info
,
ic
->
num_slots
,
ic
->
slot_size
,
ICInfo
*
icinfo
=
new
ICInfo
(
start_addr
,
slowpath_rtn_addr
,
continue_addr
,
stack_info
,
ic
->
num_slots
,
ic
->
slot_size
,
ic
->
getCallingConvention
(),
std
::
move
(
live_outs
),
return_register
,
ic
->
type_recorder
);
ic
->
getCallingConvention
(),
std
::
move
(
live_outs
),
return_register
,
ic
->
type_recorder
);
assert
(
!
ics_by_return_addr
.
count
(
slowpath_rtn_addr
));
ics_by_return_addr
[
slowpath_rtn_addr
]
=
icinfo
;
ics_by_return_addr
[
slowpath_rtn_addr
]
=
icinfo
;
registerGCTrackedICInfo
(
icinfo
);
return
std
::
unique_ptr
<
ICInfo
>
(
icinfo
);
return
std
::
unique_ptr
<
ICInfo
>
(
icinfo
);
}
}
void
deregisterCompiledPatchpoint
(
ICInfo
*
ic
)
{
void
deregisterCompiledPatchpoint
(
ICInfo
*
ic
)
{
assert
(
ics_by_return_addr
.
count
(
ic
->
slowpath_rtn_addr
));
assert
(
ics_by_return_addr
.
count
(
ic
->
slowpath_rtn_addr
));
ics_by_return_addr
.
erase
(
ic
->
slowpath_rtn_addr
);
ics_by_return_addr
.
erase
(
ic
->
slowpath_rtn_addr
);
deregisterGCTrackedICInfo
(
ic
);
}
}
ICInfo
*
getICInfo
(
void
*
rtn_addr
)
{
ICInfo
*
getICInfo
(
void
*
rtn_addr
)
{
...
@@ -305,4 +342,12 @@ bool ICInfo::shouldAttempt() {
...
@@ -305,4 +342,12 @@ bool ICInfo::shouldAttempt() {
bool
ICInfo
::
isMegamorphic
()
{
bool
ICInfo
::
isMegamorphic
()
{
return
times_rewritten
>=
IC_MEGAMORPHIC_THRESHOLD
;
return
times_rewritten
>=
IC_MEGAMORPHIC_THRESHOLD
;
}
}
void
ICInfo
::
visitGCReferences
(
gc
::
GCVisitor
*
v
)
{
for
(
const
auto
&
p
:
ics_list
)
{
for
(
auto
&
slot
:
p
->
slots
)
{
v
->
visitNonRelocatableRange
(
&
slot
.
gc_references
[
0
],
&
slot
.
gc_references
[
slot
.
gc_references
.
size
()]);
}
}
}
}
}
src/asm_writing/icinfo.h
View file @
74fce7a4
...
@@ -27,6 +27,10 @@
...
@@ -27,6 +27,10 @@
namespace
pyston
{
namespace
pyston
{
namespace
gc
{
class
GCVisitor
;
}
class
TypeRecorder
;
class
TypeRecorder
;
class
ICInfo
;
class
ICInfo
;
...
@@ -43,6 +47,8 @@ public:
...
@@ -43,6 +47,8 @@ public:
int
idx
;
// the index inside the ic
int
idx
;
// the index inside the ic
int
num_inside
;
// the number of stack frames that are currently inside this slot
int
num_inside
;
// the number of stack frames that are currently inside this slot
std
::
vector
<
void
*>
gc_references
;
void
clear
();
void
clear
();
};
};
...
@@ -85,7 +91,7 @@ public:
...
@@ -85,7 +91,7 @@ public:
void
gc_visit
(
gc
::
GCVisitor
*
visitor
);
void
gc_visit
(
gc
::
GCVisitor
*
visitor
);
void
addDependenceOn
(
ICInvalidator
&
);
void
addDependenceOn
(
ICInvalidator
&
);
void
commit
(
CommitHook
*
hook
);
void
commit
(
CommitHook
*
hook
,
std
::
vector
<
void
*>
gc_references
);
void
abort
();
void
abort
();
const
ICInfo
*
getICInfo
()
{
return
ic
;
}
const
ICInfo
*
getICInfo
()
{
return
ic
;
}
...
@@ -124,6 +130,7 @@ public:
...
@@ -124,6 +130,7 @@ public:
ICInfo
(
void
*
start_addr
,
void
*
slowpath_rtn_addr
,
void
*
continue_addr
,
StackInfo
stack_info
,
int
num_slots
,
ICInfo
(
void
*
start_addr
,
void
*
slowpath_rtn_addr
,
void
*
continue_addr
,
StackInfo
stack_info
,
int
num_slots
,
int
slot_size
,
llvm
::
CallingConv
::
ID
calling_conv
,
LiveOutSet
live_outs
,
int
slot_size
,
llvm
::
CallingConv
::
ID
calling_conv
,
LiveOutSet
live_outs
,
assembler
::
GenericRegister
return_register
,
TypeRecorder
*
type_recorder
);
assembler
::
GenericRegister
return_register
,
TypeRecorder
*
type_recorder
);
~
ICInfo
();
void
*
const
start_addr
,
*
const
slowpath_rtn_addr
,
*
const
continue_addr
;
void
*
const
start_addr
,
*
const
slowpath_rtn_addr
,
*
const
continue_addr
;
int
getSlotSize
()
{
return
slot_size
;
}
int
getSlotSize
()
{
return
slot_size
;
}
...
@@ -142,8 +149,12 @@ public:
...
@@ -142,8 +149,12 @@ public:
int
percentBackedoff
()
const
{
return
retry_backoff
;
}
int
percentBackedoff
()
const
{
return
retry_backoff
;
}
friend
class
ICSlotRewrite
;
friend
class
ICSlotRewrite
;
static
void
visitGCReferences
(
gc
::
GCVisitor
*
visitor
);
};
};
void
registerGCTrackedICInfo
(
ICInfo
*
ic
);
void
deregisterGCTrackedICInfo
(
ICInfo
*
ic
);
class
ICSetupInfo
;
class
ICSetupInfo
;
struct
CompiledFunction
;
struct
CompiledFunction
;
std
::
unique_ptr
<
ICInfo
>
registerCompiledPatchpoint
(
uint8_t
*
start_addr
,
uint8_t
*
slowpath_start_addr
,
std
::
unique_ptr
<
ICInfo
>
registerCompiledPatchpoint
(
uint8_t
*
start_addr
,
uint8_t
*
slowpath_start_addr
,
...
...
src/asm_writing/rewriter.cpp
View file @
74fce7a4
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include "codegen/unwinding.h"
#include "codegen/unwinding.h"
#include "core/common.h"
#include "core/common.h"
#include "core/stats.h"
#include "core/stats.h"
#include "gc/heap.h"
#include "runtime/types.h"
#include "runtime/types.h"
namespace
pyston
{
namespace
pyston
{
...
@@ -350,6 +351,7 @@ void RewriterVar::addAttrGuard(int offset, uint64_t val, bool negate) {
...
@@ -350,6 +351,7 @@ void RewriterVar::addAttrGuard(int offset, uint64_t val, bool negate) {
if
(
!
attr_guards
.
insert
(
std
::
make_tuple
(
offset
,
val
,
negate
)).
second
)
if
(
!
attr_guards
.
insert
(
std
::
make_tuple
(
offset
,
val
,
negate
)).
second
)
return
;
// duplicate guard detected
return
;
// duplicate guard detected
RewriterVar
*
val_var
=
rewriter
->
loadConst
(
val
);
RewriterVar
*
val_var
=
rewriter
->
loadConst
(
val
);
rewriter
->
addAction
([
=
]()
{
rewriter
->
_addAttrGuard
(
this
,
offset
,
val_var
,
negate
);
},
{
this
,
val_var
},
rewriter
->
addAction
([
=
]()
{
rewriter
->
_addAttrGuard
(
this
,
offset
,
val_var
,
negate
);
},
{
this
,
val_var
},
ActionType
::
GUARD
);
ActionType
::
GUARD
);
...
@@ -717,6 +719,15 @@ void Rewriter::_trap() {
...
@@ -717,6 +719,15 @@ void Rewriter::_trap() {
RewriterVar
*
Rewriter
::
loadConst
(
int64_t
val
,
Location
dest
)
{
RewriterVar
*
Rewriter
::
loadConst
(
int64_t
val
,
Location
dest
)
{
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
STAT_TIMER
(
t0
,
"us_timer_rewriter"
,
10
);
#if MOVING_GC
// Moving GCs need to know all existing references in the program, including those that end
// up in compiled code.
auto
al
=
gc
::
global_heap
.
getAllocationFromInteriorPointer
((
void
*
)
val
);
if
(
al
)
{
gc_references
.
push_back
(
al
->
user_data
);
}
#endif
for
(
auto
&
p
:
const_loader
.
consts
)
{
for
(
auto
&
p
:
const_loader
.
consts
)
{
if
(
p
.
first
!=
val
)
if
(
p
.
first
!=
val
)
continue
;
continue
;
...
@@ -1328,7 +1339,7 @@ void Rewriter::commit() {
...
@@ -1328,7 +1339,7 @@ void Rewriter::commit() {
}
}
#endif
#endif
rewrite
->
commit
(
this
);
rewrite
->
commit
(
this
,
std
::
move
(
gc_references
)
);
if
(
assembler
->
hasFailed
())
{
if
(
assembler
->
hasFailed
())
{
on_assemblyfail
();
on_assemblyfail
();
...
@@ -1378,6 +1389,12 @@ void Rewriter::addDependenceOn(ICInvalidator& invalidator) {
...
@@ -1378,6 +1389,12 @@ void Rewriter::addDependenceOn(ICInvalidator& invalidator) {
void
Rewriter
::
gc_visit
(
GCVisitor
*
visitor
)
{
void
Rewriter
::
gc_visit
(
GCVisitor
*
visitor
)
{
rewrite
->
gc_visit
(
visitor
);
rewrite
->
gc_visit
(
visitor
);
// A GC could happen during a rewrite, so we need to scan the list of references
// both as it is being built and after the rewrite commits.
for
(
auto
&
reference
:
gc_references
)
{
visitor
->
visitNonRelocatable
(
reference
);
}
}
}
Location
Rewriter
::
allocScratch
()
{
Location
Rewriter
::
allocScratch
()
{
...
...
src/asm_writing/rewriter.h
View file @
74fce7a4
...
@@ -442,6 +442,7 @@ protected:
...
@@ -442,6 +442,7 @@ protected:
}
}
bool
added_changing_action
;
bool
added_changing_action
;
bool
marked_inside_ic
;
bool
marked_inside_ic
;
std
::
vector
<
void
*>
gc_references
;
bool
done_guarding
;
bool
done_guarding
;
bool
isDoneGuarding
()
{
bool
isDoneGuarding
()
{
...
...
src/codegen/baseline_jit.cpp
View file @
74fce7a4
...
@@ -624,6 +624,15 @@ int JitFragmentWriter::finishCompilation() {
...
@@ -624,6 +624,15 @@ int JitFragmentWriter::finishCompilation() {
void
*
next_fragment_start
=
(
uint8_t
*
)
block
->
code
+
assembler
->
bytesWritten
();
void
*
next_fragment_start
=
(
uint8_t
*
)
block
->
code
+
assembler
->
bytesWritten
();
code_block
.
fragmentFinished
(
assembler
->
bytesWritten
(),
num_bytes_overlapping
,
next_fragment_start
);
code_block
.
fragmentFinished
(
assembler
->
bytesWritten
(),
num_bytes_overlapping
,
next_fragment_start
);
#if MOVING_GC
// If JitFragmentWriter is destroyed, we don't necessarily want the ICInfo to be destroyed also,
// because it may contain a list of references to pointers in generated code that still exists
// and we need to keep those around.
// TODO: When should these ICInfo be freed?
registerGCTrackedICInfo
(
ic_info
.
release
());
#endif
return
num_bytes_exit
;
return
num_bytes_exit
;
}
}
...
...
src/codegen/irgen.cpp
View file @
74fce7a4
...
@@ -1042,6 +1042,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames*
...
@@ -1042,6 +1042,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames*
}
}
CompiledFunction
*
cf
=
new
CompiledFunction
(
NULL
,
spec
,
NULL
,
effort
,
exception_style
,
entry_descriptor
);
CompiledFunction
*
cf
=
new
CompiledFunction
(
NULL
,
spec
,
NULL
,
effort
,
exception_style
,
entry_descriptor
);
setPointersInCodeStorage
(
&
cf
->
pointers_in_code
);
// Make sure that the instruction memory keeps the module object alive.
// Make sure that the instruction memory keeps the module object alive.
// TODO: implement this for real
// TODO: implement this for real
...
...
src/codegen/irgen/hooks.cpp
View file @
74fce7a4
...
@@ -753,6 +753,7 @@ void CompiledFunction::speculationFailed() {
...
@@ -753,6 +753,7 @@ void CompiledFunction::speculationFailed() {
}
}
}
}
std
::
unordered_set
<
CompiledFunction
*>
all_compiled_functions
;
CompiledFunction
::
CompiledFunction
(
llvm
::
Function
*
func
,
FunctionSpecialization
*
spec
,
void
*
code
,
EffortLevel
effort
,
CompiledFunction
::
CompiledFunction
(
llvm
::
Function
*
func
,
FunctionSpecialization
*
spec
,
void
*
code
,
EffortLevel
effort
,
ExceptionStyle
exception_style
,
const
OSREntryDescriptor
*
entry_descriptor
)
ExceptionStyle
exception_style
,
const
OSREntryDescriptor
*
entry_descriptor
)
:
clfunc
(
NULL
),
:
clfunc
(
NULL
),
...
@@ -766,6 +767,26 @@ CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization*
...
@@ -766,6 +767,26 @@ CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization*
times_speculation_failed
(
0
),
times_speculation_failed
(
0
),
location_map
(
nullptr
)
{
location_map
(
nullptr
)
{
assert
((
spec
!=
NULL
)
+
(
entry_descriptor
!=
NULL
)
==
1
);
assert
((
spec
!=
NULL
)
+
(
entry_descriptor
!=
NULL
)
==
1
);
#if MOVING_GC
assert
(
all_compiled_functions
.
count
(
this
)
==
0
);
all_compiled_functions
.
insert
(
this
);
#endif
}
#if MOVING_GC
CompiledFunction
::~
CompiledFunction
()
{
assert
(
all_compiled_functions
.
count
(
this
)
==
1
);
all_compiled_functions
.
erase
(
this
);
}
#endif
void
CompiledFunction
::
visitAllCompiledFunctions
(
GCVisitor
*
visitor
)
{
for
(
CompiledFunction
*
cf
:
all_compiled_functions
)
{
for
(
const
void
*
ptr
:
cf
->
pointers_in_code
)
{
visitor
->
visitNonRelocatable
(
const_cast
<
void
*>
(
ptr
));
}
}
}
}
ConcreteCompilerType
*
CompiledFunction
::
getReturnType
()
{
ConcreteCompilerType
*
CompiledFunction
::
getReturnType
()
{
...
...
src/codegen/irgen/util.cpp
View file @
74fce7a4
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "codegen/codegen.h"
#include "codegen/codegen.h"
#include "codegen/patchpoints.h"
#include "codegen/patchpoints.h"
#include "core/common.h"
#include "core/common.h"
#include "gc/gc.h"
#include "runtime/types.h"
#include "runtime/types.h"
namespace
pyston
{
namespace
pyston
{
...
@@ -99,10 +100,18 @@ llvm::Constant* getStringConstantPtr(llvm::StringRef str) {
...
@@ -99,10 +100,18 @@ llvm::Constant* getStringConstantPtr(llvm::StringRef str) {
static
llvm
::
StringMap
<
const
void
*>
relocatable_syms
;
static
llvm
::
StringMap
<
const
void
*>
relocatable_syms
;
// Pointer to a vector where we want to keep track of all the pointers written directly into
// the compiled code, which the GC needs to be aware of.
std
::
vector
<
const
void
*>*
pointers_in_code
;
void
clearRelocatableSymsMap
()
{
void
clearRelocatableSymsMap
()
{
relocatable_syms
.
clear
();
relocatable_syms
.
clear
();
}
}
void
setPointersInCodeStorage
(
std
::
vector
<
const
void
*>*
v
)
{
pointers_in_code
=
v
;
}
const
void
*
getValueOfRelocatableSym
(
const
std
::
string
&
str
)
{
const
void
*
getValueOfRelocatableSym
(
const
std
::
string
&
str
)
{
auto
it
=
relocatable_syms
.
find
(
str
);
auto
it
=
relocatable_syms
.
find
(
str
);
if
(
it
!=
relocatable_syms
.
end
())
if
(
it
!=
relocatable_syms
.
end
())
...
@@ -129,6 +138,13 @@ llvm::Constant* embedRelocatablePtr(const void* addr, llvm::Type* type, llvm::St
...
@@ -129,6 +138,13 @@ llvm::Constant* embedRelocatablePtr(const void* addr, llvm::Type* type, llvm::St
relocatable_syms
[
name
]
=
addr
;
relocatable_syms
[
name
]
=
addr
;
#if MOVING_GC
gc
::
GCAllocation
*
al
=
gc
::
global_heap
.
getAllocationFromInteriorPointer
(
const_cast
<
void
*>
(
addr
));
if
(
al
)
{
pointers_in_code
->
push_back
(
al
->
user_data
);
}
#endif
llvm
::
Type
*
var_type
=
type
->
getPointerElementType
();
llvm
::
Type
*
var_type
=
type
->
getPointerElementType
();
return
new
llvm
::
GlobalVariable
(
*
g
.
cur_module
,
var_type
,
true
,
llvm
::
GlobalVariable
::
ExternalLinkage
,
0
,
name
);
return
new
llvm
::
GlobalVariable
(
*
g
.
cur_module
,
var_type
,
true
,
llvm
::
GlobalVariable
::
ExternalLinkage
,
0
,
name
);
}
}
...
@@ -137,6 +153,14 @@ llvm::Constant* embedConstantPtr(const void* addr, llvm::Type* type) {
...
@@ -137,6 +153,14 @@ llvm::Constant* embedConstantPtr(const void* addr, llvm::Type* type) {
assert
(
type
);
assert
(
type
);
llvm
::
Constant
*
int_val
=
llvm
::
ConstantInt
::
get
(
g
.
i64
,
reinterpret_cast
<
uintptr_t
>
(
addr
),
false
);
llvm
::
Constant
*
int_val
=
llvm
::
ConstantInt
::
get
(
g
.
i64
,
reinterpret_cast
<
uintptr_t
>
(
addr
),
false
);
llvm
::
Constant
*
ptr_val
=
llvm
::
ConstantExpr
::
getIntToPtr
(
int_val
,
type
);
llvm
::
Constant
*
ptr_val
=
llvm
::
ConstantExpr
::
getIntToPtr
(
int_val
,
type
);
#if MOVING_GC
gc
::
GCAllocation
*
al
=
gc
::
global_heap
.
getAllocationFromInteriorPointer
(
const_cast
<
void
*>
(
addr
));
if
(
al
)
{
pointers_in_code
->
push_back
(
al
->
user_data
);
}
#endif
return
ptr_val
;
return
ptr_val
;
}
}
...
...
src/codegen/irgen/util.h
View file @
74fce7a4
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
#include <string>
#include <string>
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringRef.h"
namespace
llvm
{
namespace
llvm
{
...
@@ -25,6 +26,10 @@ class Function;
...
@@ -25,6 +26,10 @@ class Function;
class
Type
;
class
Type
;
}
}
namespace
gc
{
class
GCVisitor
;
}
namespace
pyston
{
namespace
pyston
{
llvm
::
Constant
*
embedRelocatablePtr
(
const
void
*
addr
,
llvm
::
Type
*
,
llvm
::
StringRef
shared_name
=
llvm
::
StringRef
());
llvm
::
Constant
*
embedRelocatablePtr
(
const
void
*
addr
,
llvm
::
Type
*
,
llvm
::
StringRef
shared_name
=
llvm
::
StringRef
());
...
@@ -35,8 +40,11 @@ llvm::Constant* getConstantInt(int64_t val, llvm::Type*);
...
@@ -35,8 +40,11 @@ llvm::Constant* getConstantInt(int64_t val, llvm::Type*);
llvm
::
Constant
*
getNullPtr
(
llvm
::
Type
*
t
);
llvm
::
Constant
*
getNullPtr
(
llvm
::
Type
*
t
);
void
clearRelocatableSymsMap
();
void
clearRelocatableSymsMap
();
void
setPointersInCodeStorage
(
std
::
vector
<
const
void
*>*
v
);
const
void
*
getValueOfRelocatableSym
(
const
std
::
string
&
str
);
const
void
*
getValueOfRelocatableSym
(
const
std
::
string
&
str
);
void
visitRelocatableSymsMap
(
gc
::
GCVisitor
*
visitor
);
void
dumpPrettyIR
(
llvm
::
Function
*
f
);
void
dumpPrettyIR
(
llvm
::
Function
*
f
);
}
}
...
...
src/core/types.h
View file @
74fce7a4
...
@@ -262,6 +262,9 @@ public:
...
@@ -262,6 +262,9 @@ public:
FunctionSpecialization
*
spec
;
FunctionSpecialization
*
spec
;
const
OSREntryDescriptor
*
entry_descriptor
;
const
OSREntryDescriptor
*
entry_descriptor
;
// Pointers that were written directly into the code, which the GC should be aware of.
std
::
vector
<
const
void
*>
pointers_in_code
;
union
{
union
{
Box
*
(
*
call
)(
Box
*
,
Box
*
,
Box
*
,
Box
**
);
Box
*
(
*
call
)(
Box
*
,
Box
*
,
Box
*
,
Box
**
);
Box
*
(
*
closure_call
)(
BoxedClosure
*
,
Box
*
,
Box
*
,
Box
*
,
Box
**
);
Box
*
(
*
closure_call
)(
BoxedClosure
*
,
Box
*
,
Box
*
,
Box
*
,
Box
**
);
...
@@ -298,6 +301,8 @@ public:
...
@@ -298,6 +301,8 @@ public:
// Call this when a speculation inside this version failed
// Call this when a speculation inside this version failed
void
speculationFailed
();
void
speculationFailed
();
static
void
visitAllCompiledFunctions
(
GCVisitor
*
visitor
);
};
};
typedef
int
FutureFlags
;
typedef
int
FutureFlags
;
...
...
src/gc/collector.cpp
View file @
74fce7a4
...
@@ -18,8 +18,10 @@
...
@@ -18,8 +18,10 @@
#include <cstdio>
#include <cstdio>
#include <cstdlib>
#include <cstdlib>
#include "asm_writing/icinfo.h"
#include "codegen/ast_interpreter.h"
#include "codegen/ast_interpreter.h"
#include "codegen/codegen.h"
#include "codegen/codegen.h"
#include "codegen/irgen/util.h"
#include "core/common.h"
#include "core/common.h"
#include "core/threading.h"
#include "core/threading.h"
#include "core/types.h"
#include "core/types.h"
...
@@ -429,6 +431,12 @@ static void markRoots(GCVisitor& visitor) {
...
@@ -429,6 +431,12 @@ static void markRoots(GCVisitor& visitor) {
for
(
auto
weakref
:
weakrefs_needing_callback_list
)
{
for
(
auto
weakref
:
weakrefs_needing_callback_list
)
{
visitor
.
visit
(
weakref
);
visitor
.
visit
(
weakref
);
}
}
GC_TRACE_LOG
(
"Looking at generated code pointers
\n
"
);
#if MOVING_GC
ICInfo
::
visitGCReferences
(
&
visitor
);
CompiledFunction
::
visitAllCompiledFunctions
(
&
visitor
);
#endif
}
}
static
void
finalizationOrderingFindReachable
(
Box
*
obj
)
{
static
void
finalizationOrderingFindReachable
(
Box
*
obj
)
{
...
...
src/gc/gc.h
View file @
74fce7a4
...
@@ -86,6 +86,14 @@ public:
...
@@ -86,6 +86,14 @@ public:
virtual
void
visitRedundantRange
(
void
**
start
,
void
**
end
)
{}
virtual
void
visitRedundantRange
(
void
**
start
,
void
**
end
)
{}
virtual
void
visitPotentialRedundant
(
void
*
p
)
{}
virtual
void
visitPotentialRedundant
(
void
*
p
)
{}
virtual
void
visitPotentialRangeRedundant
(
void
*
const
*
start
,
void
*
const
*
end
)
{}
virtual
void
visitPotentialRangeRedundant
(
void
*
const
*
start
,
void
*
const
*
end
)
{}
// Visit pointers to objects that we know cannot be moved.
// This is often used to scan a pointer that's a copy of a pointer stored in a place that
// we cannot easily scanned (like generated code).
// This default to visitPotential for now (which also cannot be moved) but we may want to
// change that later for performance.
void
visitNonRelocatable
(
void
*
p
)
{
visitPotential
(
p
);
}
void
visitNonRelocatableRange
(
void
**
start
,
void
**
end
)
{
visitPotentialRange
(
start
,
end
);
}
};
};
enum
class
GCKind
:
uint8_t
{
enum
class
GCKind
:
uint8_t
{
...
...
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