Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
GHC
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tobias Decking
GHC
Commits
3c8ad7e0
Commit
3c8ad7e0
authored
May 03, 2019
by
Ben Gamari
🐢
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
NonMovingMark: Optimize representation of mark queue
This shortens MarkQueueEntry by 30% (one word)
parent
eb465927
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
38 additions
and
13 deletions
+38
-13
rts/sm/NonMovingMark.c
rts/sm/NonMovingMark.c
+16
-10
rts/sm/NonMovingMark.h
rts/sm/NonMovingMark.h
+22
-3
No files found.
rts/sm/NonMovingMark.c
View file @
3c8ad7e0
...
...
@@ -401,7 +401,6 @@ markQueuePushClosureGC (MarkQueue *q, StgClosure *p)
}
MarkQueueEnt
ent
=
{
.
type
=
MARK_CLOSURE
,
.
mark_closure
=
{
.
p
=
UNTAG_CLOSURE
(
p
),
.
origin
=
NULL
,
...
...
@@ -430,8 +429,12 @@ void push_closure (MarkQueue *q,
// }
#endif
// This must be true as origin points to a pointer and therefore must be
// word-aligned. However, we check this as otherwise we would confuse this
// with a mark_array entry
ASSERT
(((
uintptr_t
)
origin
&
0x3
)
==
0
);
MarkQueueEnt
ent
=
{
.
type
=
MARK_CLOSURE
,
.
mark_closure
=
{
.
p
=
UNTAG_CLOSURE
(
p
),
.
origin
=
origin
,
...
...
@@ -450,10 +453,9 @@ void push_array (MarkQueue *q,
return
;
MarkQueueEnt
ent
=
{
.
type
=
MARK_ARRAY
,
.
mark_array
=
{
.
array
=
array
,
.
start_index
=
start_index
.
start_index
=
(
start_index
<<
16
)
|
0x3
,
}
};
push
(
q
,
&
ent
);
...
...
@@ -716,7 +718,7 @@ again:
// Is this the first block of the queue?
if
(
q
->
blocks
->
link
==
NULL
)
{
// Yes, therefore queue is empty...
MarkQueueEnt
none
=
{
.
type
=
NULL_ENTRY
};
MarkQueueEnt
none
=
{
.
null_entry
=
{
.
p
=
NULL
}
};
return
none
;
}
else
{
// No, unwind to the previous block and try popping again...
...
...
@@ -1492,13 +1494,13 @@ nonmovingMark (MarkQueue *queue)
count
++
;
MarkQueueEnt
ent
=
markQueuePop
(
queue
);
switch
(
ent
.
type
)
{
switch
(
nonmovingMarkQueueEntryType
(
&
ent
)
)
{
case
MARK_CLOSURE
:
mark_closure
(
queue
,
ent
.
mark_closure
.
p
,
ent
.
mark_closure
.
origin
);
break
;
case
MARK_ARRAY
:
{
const
StgMutArrPtrs
*
arr
=
ent
.
mark_array
.
array
;
StgWord
start
=
ent
.
mark_array
.
start_index
;
StgWord
start
=
ent
.
mark_array
.
start_index
>>
16
;
StgWord
end
=
start
+
MARK_ARRAY_CHUNK_LENGTH
;
if
(
end
<
arr
->
ptrs
)
{
markQueuePushArray
(
queue
,
ent
.
mark_array
.
array
,
end
);
...
...
@@ -1743,13 +1745,17 @@ void nonmovingResurrectThreads (struct MarkQueue_ *queue, StgTSO **resurrected_t
void
printMarkQueueEntry
(
MarkQueueEnt
*
ent
)
{
if
(
ent
->
type
==
MARK_CLOSURE
)
{
switch
(
nonmovingMarkQueueEntryType
(
ent
))
{
case
MARK_CLOSURE
:
debugBelch
(
"Closure: "
);
printClosure
(
ent
->
mark_closure
.
p
);
}
else
if
(
ent
->
type
==
MARK_ARRAY
)
{
break
;
case
MARK_ARRAY
:
debugBelch
(
"Array
\n
"
);
}
else
{
break
;
case
NULL_ENTRY
:
debugBelch
(
"End of mark
\n
"
);
break
;
}
}
...
...
rts/sm/NonMovingMark.h
View file @
3c8ad7e0
...
...
@@ -43,9 +43,16 @@ enum EntryType {
*/
typedef
struct
{
enum
EntryType
type
;
// All pointers should be untagged
// Which kind of mark queue entry we have is determined by the low bits of
// the second word: they must be zero in the case of a mark_closure entry
// (since the second word of a mark_closure entry points to a pointer and
// pointers must be word-aligned). In the case of a mark_array we set them
// to 0x3 (the value of start_index is shifted to the left to accomodate
// this). null_entry where p==NULL is used to indicate the end of the queue.
union
{
struct
{
void
*
p
;
// must be NULL
}
null_entry
;
struct
{
StgClosure
*
p
;
// the object to be marked
StgClosure
**
origin
;
// field where this reference was found.
...
...
@@ -53,11 +60,23 @@ typedef struct {
}
mark_closure
;
struct
{
const
StgMutArrPtrs
*
array
;
StgWord
start_index
;
StgWord
start_index
;
// start index is shifted to the left by 16 bits
}
mark_array
;
};
}
MarkQueueEnt
;
INLINE_HEADER
enum
EntryType
nonmovingMarkQueueEntryType
(
MarkQueueEnt
*
ent
)
{
if
(
ent
->
null_entry
.
p
==
NULL
)
{
return
NULL_ENTRY
;
}
else
if
(((
uintptr_t
)
ent
->
mark_closure
.
origin
&
TAG_BITS
)
==
0
)
{
return
MARK_CLOSURE
;
}
else
{
ASSERT
((
ent
->
mark_array
.
start_index
&
TAG_BITS
)
==
0x3
);
return
MARK_ARRAY
;
}
}
typedef
struct
{
// index of first *unused* queue entry
uint32_t
head
;
...
...
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