Commit 69488b17 authored by Anton Bikineev's avatar Anton Bikineev Committed by Commit Bot

heap: Don't call write barrier on vector reallocations

This CL reorders reallocation scenario as follows:
1) allocating a new buffer;
2) moving elements in the current buffer to the new one ***without
   tracing them or executing write barriers on them***
3) resetting HeapVector's pointer to the new buffer;
4) executing write barrier on the new buffer.

The followup to the CL will be introducing the same optimization for
HashTable.

Bug: 1021889

Change-Id: I367165ba26045d3a4ca967c7f9f006ff88be4ed4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1899883
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714926}
parent a0ab2c88
......@@ -487,12 +487,21 @@ class ConstructTraits<blink::Member<T>, Traits, Allocator> {
STATIC_ONLY(ConstructTraits);
public:
template <typename... Args>
static blink::Member<T>* Construct(void* location, Args&&... args) {
return new (NotNull, location)
blink::Member<T>(std::forward<Args>(args)...);
}
static void NotifyNewElement(blink::Member<T>* element) {
element->WriteBarrier();
}
template <typename... Args>
static blink::Member<T>* ConstructAndNotifyElement(void* location,
Args&&... args) {
blink::Member<T>* object =
new (NotNull, location) blink::Member<T>(std::forward<Args>(args)...);
object->WriteBarrier();
blink::Member<T>* object = Construct(location, std::forward<Args>(args)...);
NotifyNewElement(object);
return object;
}
......
......@@ -21,15 +21,24 @@ class ConstructTraits {
public:
// Construct a single element that would otherwise be constructed using
// placement new.
template <typename... Args>
static T* Construct(void* location, Args&&... args) {
return new (NotNull, location) T(std::forward<Args>(args)...);
}
// After constructing elements using memcopy or memmove (or similar)
// |NotifyNewElement| needs to be called to propagate that information.
static void NotifyNewElement(T* element) {
Allocator::template NotifyNewObject<T, Traits>(element);
}
template <typename... Args>
static T* ConstructAndNotifyElement(void* location, Args&&... args) {
T* object = new (NotNull, location) T(std::forward<Args>(args)...);
Allocator::template NotifyNewObject<T, Traits>(object);
T* object = Construct(location, std::forward<Args>(args)...);
NotifyNewElement(object);
return object;
}
// After constructing elements using memcopy or memmove (or similar)
// |NotifyNewElements| needs to be called to propagate that information.
static void NotifyNewElements(T* array, size_t len) {
Allocator::template NotifyNewObjects<T, Traits>(array, len);
}
......
......@@ -1353,7 +1353,7 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
DCHECK(!IsEmptyOrDeletedBucket(*entry));
// Translate constructs an element so we need to notify using the trait. Avoid
// doing that in the translator so that they can be easily customized.
ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElements(entry, 1);
ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElement(entry);
++key_count_;
......@@ -1421,7 +1421,7 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
DCHECK(!IsEmptyOrDeletedBucket(*entry));
// Translate constructs an element so we need to notify using the trait. Avoid
// doing that in the translator so that they can be easily customized.
ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElements(entry, 1);
ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElement(entry);
++key_count_;
if (ShouldExpand())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment