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
dffaf33c
Commit
dffaf33c
authored
Sep 01, 2015
by
Rudi Chen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Scan pointers used in inline caches and scan relocatable symbols.
parent
1c9ebd80
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
107 additions
and
5 deletions
+107
-5
src/asm_writing/icinfo.cpp
src/asm_writing/icinfo.cpp
+49
-2
src/asm_writing/icinfo.h
src/asm_writing/icinfo.h
+12
-1
src/asm_writing/rewriter.cpp
src/asm_writing/rewriter.cpp
+12
-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/util.cpp
src/codegen/irgen/util.cpp
+2
-1
src/codegen/irgen/util.h
src/codegen/irgen/util.h
+7
-0
src/gc/collector.cpp
src/gc/collector.cpp
+7
-0
src/gc/gc.h
src/gc/gc.h
+8
-0
No files found.
src/asm_writing/icinfo.cpp
View file @
dffaf33c
...
@@ -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
{
...
@@ -82,7 +86,7 @@ uint8_t* ICSlotRewrite::getSlotStart() {
...
@@ -82,7 +86,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 +122,8 @@ void ICSlotRewrite::commit(CommitHook* hook) {
...
@@ -118,6 +122,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 +193,25 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(const char* debug_name) {
...
@@ -187,6 +193,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 +232,18 @@ ICInfo::ICInfo(void* start_addr, void* slowpath_rtn_addr, void* continue_addr, S
...
@@ -207,9 +232,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 +285,19 @@ std::unique_ptr<ICInfo> registerCompiledPatchpoint(uint8_t* start_addr, uint8_t*
...
@@ -251,14 +285,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 +344,12 @@ bool ICInfo::shouldAttempt() {
...
@@ -305,4 +344,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 @
dffaf33c
...
@@ -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 @
dffaf33c
...
@@ -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
();
...
...
src/asm_writing/rewriter.h
View file @
dffaf33c
...
@@ -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 @
dffaf33c
...
@@ -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/util.cpp
View file @
dffaf33c
...
@@ -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
{
...
@@ -97,7 +98,7 @@ llvm::Constant* getStringConstantPtr(llvm::StringRef str) {
...
@@ -97,7 +98,7 @@ llvm::Constant* getStringConstantPtr(llvm::StringRef str) {
// It's slightly easier to emit them as integers (there are primitive integer constants but not pointer constants),
// It's slightly easier to emit them as integers (there are primitive integer constants but not pointer constants),
// but doing it this way makes it clearer what's going on.
// but doing it this way makes it clearer what's going on.
static
llvm
::
StringMap
<
const
void
*>
relocatable_syms
;
llvm
::
StringMap
<
const
void
*>
relocatable_syms
;
void
clearRelocatableSymsMap
()
{
void
clearRelocatableSymsMap
()
{
relocatable_syms
.
clear
();
relocatable_syms
.
clear
();
...
...
src/codegen/irgen/util.h
View file @
dffaf33c
...
@@ -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
());
...
@@ -37,6 +42,8 @@ llvm::Constant* getNullPtr(llvm::Type* t);
...
@@ -37,6 +42,8 @@ llvm::Constant* getNullPtr(llvm::Type* t);
void
clearRelocatableSymsMap
();
void
clearRelocatableSymsMap
();
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/gc/collector.cpp
View file @
dffaf33c
...
@@ -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,11 @@ static void markRoots(GCVisitor& visitor) {
...
@@ -429,6 +431,11 @@ 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
);
#endif
}
}
static
void
finalizationOrderingFindReachable
(
Box
*
obj
)
{
static
void
finalizationOrderingFindReachable
(
Box
*
obj
)
{
...
...
src/gc/gc.h
View file @
dffaf33c
...
@@ -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