Commit Graph

20 Commits

Author SHA1 Message Date
Anna Zaks
5320deff66 Tweak the memory ordering in ConcurrentMap
Make sure the memory synchronization ordering on success is strictly stronger than the memory ordering of failure. This addresses a race reported by TSan when having both Swift tests and the runtime TSanified.
2016-04-06 11:54:07 -07:00
Davide Italiano
59ed25c208 [FreeBSD] Include <stdio.h>, needed for printf(). 2016-02-29 19:40:22 +00:00
John McCall
fc261045a5 Optimize the number of accesses performed on ConcurrentMap
and MetadataCache and fix a re-entrancy bug in metadata
instantiation.

The re-entrancy bug is that we were holding the instantiation
lock of a metadata cache while instantiating metadata.  Doing
so prevents us from creating a different instantiation if
it's needed by the outer instantiation.  This is already
possible, but it's much more likely in a patch I'm working on
to only store the minimal metadata for generic parameters
in generic types.

The same bug could also show up as a deadlock between threads,
so a recursive lock would not be a good fix.  Instead, we add
a condition variable to the metadata cache.  When fetching
metadata, we look for a node in the concurrent map, eagerly
creating an empty one if none currently exists.  If lookup
finds an empty node, we wait on the condition variable for
the node to become populated.  If lookup succeeds in creating
an empty node, we instantiate the metadata, grab the lock,
populate the node, and notify the condition variable.

Safely creating an empty node without any metadata present
requires us to move the key data into the map entry.  That,
plus a few other invariant shifts, makes it sensible to
give the user of ConcurrentMap more control over the
allocation of map nodes and the layout of keys.  That, in
turn, allows us to change the contract so that keys can be
more complex than just a hash code.  Instead of incrementing
hash codes and re-performing the lookup, we just insist
that lookup keys be totally ordered.

For now, I've kept the uniform use of hash codes as a
component of the key for MetadataCaches.  However, hash
codes aren't really profitable for small keys, and we should
probably use direct comparisons instead.

We should also switch the safer metadata caches (i.e. the
ones that don't involve calling an arbitrary instantiation
function, like MetatypeMetadataCache) over to directly use
ConcurrentMap.

LLDB's requirement that we maintain a linked list of metadata
cache instantiations with a known layout means we can't yet
remove the CacheEntry's redundant copy of the generic
arguments.
2016-02-25 01:11:57 -08:00
Nadav Rotem
866b44cbae [Debug] Add add a method to dump dotty style graph.
Add add a method to dump the metadata caches as a dotty graph.
2016-02-09 23:14:27 -08:00
practicalswift
2e8190016d [gardening] Fix recently introduced typo: "collissions" → "collisions" 2016-02-09 22:46:29 +01:00
Nadav Rotem
cdbf839f6c [Runtime Mem] Convert the metadata map from open to closed hash map.
This change cuts the number of mallocs() in the metadata caches in half.

The current metadata cache data structure uses a linked list for each entry in
the tree to handle collissions.  This means that we need at least two memory
allocations for each entry, one for the tree node and one for the linked list
node.

This commit changes the map used by the metadata caches from an open hash map
(that embeds a linked list at each entry) into an closed map that uses a
different hash value for each entry. With this change we no longer accept
collissions and it is now the responsibility of the user to prevent collissions.
The new get/trySet API makes this responsibility explicit. The new design also
goes well with the current design where hashing is done externally and the fact
that we don't save the full key, just the hash and the value to save memory.

This change reduces the number of allocated objects per entry in half. Instead
of allocating two 32-byte objects (one for the tree node and one for the linked
list) we just allocate a single entry that contains the hash and the value.

Unfortunately, values that are made of two 64-bit pointers (like protocol
conformance entries) are now too big for the 32-byte tree entry and are rounded
up to 48 bytes. In practice this is not a big deal because malloc has 48-byte pool
entries.
2016-02-08 22:57:50 -08:00
Nadav Rotem
38e3a8c8d3 Fix typos in the comments. 2016-02-08 22:57:50 -08:00
practicalswift
f91525a10f Consistent placement of "-*- [language] -*-===//" in header. 2016-01-04 09:46:20 +01:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Tighe Racicot
270e018757 Whoops, undo unnecessary correction 2015-12-16 19:33:39 -07:00
Tighe Racicot
1a42043505 Fix minor typos 2015-12-16 19:26:47 -07:00
Nadav Rotem
d214e367d0 Remove the custom memory allocator. It was not effective in accelerating the metadata lookups and Greg and Dave have suggested other solutions for accelerating this call.
Swift SVN r24869
2015-01-31 00:44:17 +00:00
Nadav Rotem
44506fff22 Rename the method. NFC.
Swift SVN r24867
2015-01-31 00:44:15 +00:00
Nadav Rotem
278bc16f43 Rename the method. NFC.
Swift SVN r24866
2015-01-31 00:44:15 +00:00
Nadav Rotem
26261cd1fe Allow the allocator to free memory.
Swift SVN r24865
2015-01-31 00:44:14 +00:00
Nadav Rotem
f2a6e11932 Add a clear() method to delete all links.
Swift SVN r24864
2015-01-31 00:44:13 +00:00
Nadav Rotem
2236ff8153 Use std::distance and add the missing typedefs needed for stl
Swift SVN r24863
2015-01-31 00:44:10 +00:00
Nadav Rotem
0b9a79b38b Add a concurrent bump-ptr memory allocator.
Swift SVN r24702
2015-01-24 01:08:04 +00:00
Nadav Rotem
1e02da9465 Add a concurrent memory bank
Swift SVN r24701
2015-01-24 01:08:04 +00:00
Nadav Rotem
b1ca4bfab5 Move the concurrent utilities to the /include directory
Swift SVN r24699
2015-01-24 01:08:03 +00:00