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
79e4f2c4
Commit
79e4f2c4
authored
Aug 15, 2015
by
Marius Wachtler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switch our Python set implementation to use a llvm::DenseSet
parent
31f72898
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
31 additions
and
39 deletions
+31
-39
src/runtime/set.cpp
src/runtime/set.cpp
+15
-23
src/runtime/set.h
src/runtime/set.h
+2
-2
src/runtime/types.h
src/runtime/types.h
+14
-14
No files found.
src/runtime/set.cpp
View file @
79e4f2c4
...
...
@@ -29,15 +29,9 @@ void BoxedSet::gcHandler(GCVisitor* v, Box* b) {
Box
::
gcHandler
(
v
,
b
);
BoxedSet
*
s
=
(
BoxedSet
*
)
b
;
// This feels like a cludge, but we need to find anything that
// the unordered_map might have allocated.
// Another way to handle this would be to rt_alloc the unordered_map
// as well, though that incurs extra memory dereferences which would
// be nice to avoid.
void
**
start
=
(
void
**
)
&
s
->
s
;
void
**
end
=
start
+
(
sizeof
(
s
->
s
)
/
8
);
v
->
visitPotentialRange
(
start
,
end
);
for
(
auto
&&
p
:
s
->
s
)
{
v
->
visit
(
p
.
value
);
}
}
namespace
set
{
...
...
@@ -54,7 +48,7 @@ public:
bool
hasNext
()
{
return
it
!=
s
->
s
.
end
();
}
Box
*
next
()
{
Box
*
rtn
=
*
it
;
Box
*
rtn
=
it
->
value
;
++
it
;
return
rtn
;
}
...
...
@@ -136,13 +130,13 @@ static Box* _setRepr(BoxedSet* self, const char* type_name) {
chars
.
push_back
(
'['
);
bool
first
=
true
;
for
(
Box
*
elt
:
self
->
s
)
{
for
(
auto
&&
elt
:
self
->
s
)
{
if
(
!
first
)
{
chars
.
push_back
(
','
);
chars
.
push_back
(
' '
);
}
BoxedString
*
str
=
static_cast
<
BoxedString
*>
(
repr
(
elt
));
BoxedString
*
str
=
static_cast
<
BoxedString
*>
(
repr
(
elt
.
value
));
chars
.
insert
(
chars
.
end
(),
str
->
s
().
begin
(),
str
->
s
().
end
());
first
=
false
;
...
...
@@ -173,10 +167,10 @@ Box* setOrSet(BoxedSet* lhs, BoxedSet* rhs) {
BoxedSet
*
rtn
=
new
(
lhs
->
cls
)
BoxedSet
();
for
(
Box
*
elt
:
lhs
->
s
)
{
for
(
auto
&&
elt
:
lhs
->
s
)
{
rtn
->
s
.
insert
(
elt
);
}
for
(
Box
*
elt
:
rhs
->
s
)
{
for
(
auto
&&
elt
:
rhs
->
s
)
{
rtn
->
s
.
insert
(
elt
);
}
return
rtn
;
...
...
@@ -188,7 +182,7 @@ Box* setAndSet(BoxedSet* lhs, BoxedSet* rhs) {
BoxedSet
*
rtn
=
new
(
lhs
->
cls
)
BoxedSet
();
for
(
Box
*
elt
:
lhs
->
s
)
{
for
(
auto
&&
elt
:
lhs
->
s
)
{
if
(
rhs
->
s
.
count
(
elt
))
rtn
->
s
.
insert
(
elt
);
}
...
...
@@ -201,7 +195,7 @@ Box* setSubSet(BoxedSet* lhs, BoxedSet* rhs) {
BoxedSet
*
rtn
=
new
(
lhs
->
cls
)
BoxedSet
();
for
(
Box
*
elt
:
lhs
->
s
)
{
for
(
auto
&&
elt
:
lhs
->
s
)
{
// TODO if len(rhs) << len(lhs), it might be more efficient
// to delete the elements of rhs from lhs?
if
(
rhs
->
s
.
count
(
elt
)
==
0
)
...
...
@@ -216,12 +210,12 @@ Box* setXorSet(BoxedSet* lhs, BoxedSet* rhs) {
BoxedSet
*
rtn
=
new
(
lhs
->
cls
)
BoxedSet
();
for
(
Box
*
elt
:
lhs
->
s
)
{
for
(
auto
&&
elt
:
lhs
->
s
)
{
if
(
rhs
->
s
.
count
(
elt
)
==
0
)
rtn
->
s
.
insert
(
elt
);
}
for
(
Box
*
elt
:
rhs
->
s
)
{
for
(
auto
&&
elt
:
rhs
->
s
)
{
if
(
lhs
->
s
.
count
(
elt
)
==
0
)
rtn
->
s
.
insert
(
elt
);
}
...
...
@@ -447,7 +441,7 @@ Box* setPop(BoxedSet* self) {
raiseExcHelper
(
KeyError
,
"pop from an empty set"
);
auto
it
=
self
->
s
.
begin
();
Box
*
rtn
=
*
it
;
Box
*
rtn
=
it
->
value
;
self
->
s
.
erase
(
it
);
return
rtn
;
}
...
...
@@ -489,10 +483,8 @@ Box* setHash(BoxedSet* self) {
RELEASE_ASSERT
(
isSubclass
(
self
->
cls
,
frozenset_cls
),
""
);
int64_t
rtn
=
1927868237L
;
for
(
Box
*
e
:
self
->
s
)
{
BoxedInt
*
h
=
hash
(
e
);
assert
(
PyInt_Check
(
h
));
rtn
^=
h
->
n
+
0x9e3779b9
+
(
rtn
<<
6
)
+
(
rtn
>>
2
);
for
(
auto
&&
e
:
self
->
s
)
{
rtn
^=
e
.
hash
+
0x9e3779b9
+
(
rtn
<<
6
)
+
(
rtn
>>
2
);
}
return
boxInt
(
rtn
);
...
...
src/runtime/set.h
View file @
79e4f2c4
...
...
@@ -15,7 +15,7 @@
#ifndef PYSTON_RUNTIME_SET_H
#define PYSTON_RUNTIME_SET_H
#include
<unordered_set>
#include
"llvm/ADT/DenseSet.h"
#include "core/types.h"
#include "runtime/types.h"
...
...
@@ -29,7 +29,7 @@ extern "C" Box* createSet();
class
BoxedSet
:
public
Box
{
public:
typedef
std
::
unordered_set
<
Box
*
,
PyHasher
,
PyEq
,
StlCompatAllocator
<
Box
*>
>
Set
;
typedef
llvm
::
DenseSet
<
BoxAndHash
,
BoxAndHash
::
Comparisons
>
Set
;
Set
s
;
Box
**
weakreflist
;
/* List of weak references */
...
...
src/runtime/types.h
View file @
79e4f2c4
...
...
@@ -659,19 +659,16 @@ struct PyLt {
bool
operator
()(
Box
*
,
Box
*
)
const
;
};
class
BoxedDict
:
public
Box
{
public:
// llvm::DenseMap doesn't store the original hash values, choosing to instead
// check for equality more often. This is probably a good tradeoff when the keys
// are pointers and comparison is cheap, but we want to make sure that keys with
// different hash values don't get compared.
struct
BoxAndHash
{
// llvm::DenseMap doesn't store the original hash values, choosing to instead
// check for equality more often. This is probably a good tradeoff when the keys
// are pointers and comparison is cheap, but we want to make sure that keys with
// different hash values don't get compared.
struct
BoxAndHash
{
Box
*
value
;
size_t
hash
;
BoxAndHash
(
Box
*
value
)
:
value
(
value
),
hash
(
PyHasher
()(
value
))
{}
BoxAndHash
(
Box
*
value
,
size_t
hash
)
:
value
(
value
),
hash
(
hash
)
{}
};
struct
Comparisons
{
static
bool
isEqual
(
BoxAndHash
lhs
,
BoxAndHash
rhs
)
{
...
...
@@ -687,8 +684,11 @@ public:
static
BoxAndHash
getTombstoneKey
()
{
return
BoxAndHash
((
Box
*
)
-
2
,
0
);
}
static
unsigned
getHashValue
(
BoxAndHash
val
)
{
return
val
.
hash
;
}
};
};
typedef
llvm
::
DenseMap
<
BoxAndHash
,
Box
*
,
Comparisons
>
DictMap
;
class
BoxedDict
:
public
Box
{
public:
typedef
llvm
::
DenseMap
<
BoxAndHash
,
Box
*
,
BoxAndHash
::
Comparisons
>
DictMap
;
DictMap
d
;
...
...
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