зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1665338 - Make GC cell header word atomic to avoid race in compacting GC r=sfink,decoder
Differential Revision: https://phabricator.services.mozilla.com/D90389
This commit is contained in:
Родитель
8804eb9be3
Коммит
6bb01d4a27
|
@ -7,6 +7,8 @@
|
|||
#ifndef gc_Cell_h
|
||||
#define gc_Cell_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "gc/GCEnum.h"
|
||||
|
@ -115,7 +117,13 @@ class CellColor {
|
|||
struct Cell {
|
||||
protected:
|
||||
// Cell header word. Stores GC flags and derived class data.
|
||||
uintptr_t header_;
|
||||
//
|
||||
// This is atomic since it can be read from and written to by different
|
||||
// threads during compacting GC, in a limited way. Specifically, writes that
|
||||
// update the derived class data can race with reads that check the forwarded
|
||||
// flag. The writes do not change the forwarded flag (which is always false in
|
||||
// this situation).
|
||||
mozilla::Atomic<uintptr_t, mozilla::MemoryOrdering::Relaxed> header_;
|
||||
|
||||
public:
|
||||
static_assert(gc::CellFlagBitsReservedForGC >= 3,
|
||||
|
@ -681,7 +689,7 @@ class alignas(gc::CellAlignBytes) TenuredCellWithNonGCPointer
|
|||
// flags are also always clear). This means we don't need to use masking to
|
||||
// get and set the pointer.
|
||||
MOZ_ASSERT(flags() == 0);
|
||||
return reinterpret_cast<PtrT*>(header_);
|
||||
return reinterpret_cast<PtrT*>(uintptr_t(header_));
|
||||
}
|
||||
|
||||
void setHeaderPtr(PtrT* newValue) {
|
||||
|
@ -747,7 +755,7 @@ class alignas(gc::CellAlignBytes) CellWithTenuredGCPointer : public BaseCell {
|
|||
// masking to get and set the pointer.
|
||||
staticAsserts();
|
||||
MOZ_ASSERT(this->flags() == 0);
|
||||
return reinterpret_cast<PtrT*>(this->header_);
|
||||
return reinterpret_cast<PtrT*>(uintptr_t(this->header_));
|
||||
}
|
||||
|
||||
void unbarrieredSetHeaderPtr(PtrT* newValue) {
|
||||
|
|
|
@ -8,13 +8,13 @@ import gdb
|
|||
def get_header_ptr(value, ptr_t):
|
||||
# Return the pointer stored in Cell::header_ for subclasses of
|
||||
# TenuredCellWithNonGCPointer and CellWithTenuredGCPointer.
|
||||
return value['header_'].cast(ptr_t)
|
||||
return value['header_']['mValue'].cast(ptr_t)
|
||||
|
||||
|
||||
def get_header_length_and_flags(value):
|
||||
def get_header_length_and_flags(value, cache):
|
||||
# Return the length and flags values for subclasses of
|
||||
# CellWithLengthAndFlags.
|
||||
flags = value['header_']
|
||||
flags = value['header_']['mValue'].cast(cache.uintptr_t)
|
||||
try:
|
||||
length = value['length_']
|
||||
except gdb.error:
|
||||
|
|
|
@ -44,7 +44,7 @@ class JSStringPtr(Common):
|
|||
|
||||
def chars(self):
|
||||
d = self.value['d']
|
||||
length, flags = get_header_length_and_flags(self.value)
|
||||
length, flags = get_header_length_and_flags(self.value, self.cache)
|
||||
|
||||
corrupt = {
|
||||
0x2f2f2f2f: 'JS_FRESH_NURSERY_PATTERN',
|
||||
|
|
|
@ -204,6 +204,7 @@ class TypeCache(object):
|
|||
# enough.
|
||||
self.void_t = gdb.lookup_type('void')
|
||||
self.void_ptr_t = self.void_t.pointer()
|
||||
self.uintptr_t = gdb.lookup_type('uintptr_t')
|
||||
try:
|
||||
self.JSString_ptr_t = gdb.lookup_type('JSString').pointer()
|
||||
self.JSSymbol_ptr_t = gdb.lookup_type('JS::Symbol').pointer()
|
||||
|
|
|
@ -126,12 +126,6 @@ extern "C" const char* __tsan_default_suppressions() {
|
|||
// Bug 1600594
|
||||
"race:nsThread::SizeOfEventQueues\n"
|
||||
|
||||
// Bug 1600895, bug 1647702
|
||||
"race:UpdateArenaPointersTyped<js::ObjectGroup>\n"
|
||||
"race:UpdateArenaPointersTyped<js::Shape>\n"
|
||||
"race:UpdateArenaPointersTyped<JSObject>\n"
|
||||
"race:JSObject::fixupAfterMovingGC\n"
|
||||
|
||||
// Bug 1601286
|
||||
"race:setFlagBit\n"
|
||||
"race:isFatInline\n"
|
||||
|
|
Загрузка…
Ссылка в новой задаче