Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
dart::FieldTable Class Reference

#include <field_table.h>

Public Member Functions

 FieldTable (Isolate *isolate, IsolateGroup *isolate_group=nullptr)
 
 ~FieldTable ()
 
bool IsReadyToUse () const
 
void MarkReadyToUse ()
 
intptr_t NumFieldIds () const
 
intptr_t Capacity () const
 
ObjectPtrtable ()
 
void FreeOldTables ()
 
bool IsValidIndex (intptr_t index) const
 
bool Register (const Field &field, intptr_t expected_field_id=-1)
 
void AllocateIndex (intptr_t index)
 
void Free (intptr_t index)
 
ObjectPtr At (intptr_t index, bool concurrent_use=false) const
 
void SetAt (intptr_t index, ObjectPtr raw_instance, bool concurrent_use=false)
 
FieldTableClone (Isolate *for_isolate, IsolateGroup *for_isolate_group=nullptr)
 
void VisitObjectPointers (ObjectPointerVisitor *visitor)
 

Static Public Member Functions

static intptr_t FieldOffsetFor (intptr_t field_id)
 

Static Public Attributes

static constexpr int kInitialCapacity = 512
 
static constexpr int kCapacityIncrement = 256
 

Detailed Description

Definition at line 23 of file field_table.h.

Constructor & Destructor Documentation

◆ FieldTable()

dart::FieldTable::FieldTable ( Isolate isolate,
IsolateGroup isolate_group = nullptr 
)
inlineexplicit

Definition at line 25 of file field_table.h.

26 : top_(0),
27 capacity_(0),
28 free_head_(-1),
29 table_(nullptr),
30 old_tables_(new MallocGrowableArray<ObjectPtr*>()),
31 isolate_(isolate),
32 isolate_group_(isolate_group),
33 is_ready_to_use_(isolate == nullptr) {}

◆ ~FieldTable()

dart::FieldTable::~FieldTable ( )

Definition at line 19 of file field_table.cc.

19 {
21 delete old_tables_; // Allocated in FieldTable::FieldTable()
22 free(table_); // Allocated in FieldTable::Grow()
23}
void FreeOldTables()
Definition: field_table.cc:45

Member Function Documentation

◆ AllocateIndex()

void dart::FieldTable::AllocateIndex ( intptr_t  index)

Definition at line 91 of file field_table.cc.

91 {
92 if (index >= capacity_) {
93 const intptr_t new_capacity = index + kCapacityIncrement;
94 Grow(new_capacity);
95 }
96
97 ASSERT(table_[index] == ObjectPtr());
98 if (index >= top_) {
99 top_ = index + 1;
100 }
101}
static constexpr int kCapacityIncrement
Definition: field_table.h:97
#define ASSERT(E)

◆ At()

ObjectPtr dart::FieldTable::At ( intptr_t  index,
bool  concurrent_use = false 
) const
inline

Definition at line 62 of file field_table.h.

62 {
63 ASSERT(IsValidIndex(index));
64 if (concurrent_use) {
65 ObjectPtr* table =
66 reinterpret_cast<const AcqRelAtomic<ObjectPtr*>*>(&table_)->load();
67 return reinterpret_cast<AcqRelAtomic<ObjectPtr>*>(&table[index])->load();
68 } else {
69 // There is no concurrent access expected for this field, so we avoid
70 // using atomics. This will allow us to detect via TSAN if there are
71 // racy uses.
72 return table_[index];
73 }
74 }
SI T load(const P *ptr)
Definition: Transform_inl.h:98
ObjectPtr * table()
Definition: field_table.h:43
bool IsValidIndex(intptr_t index) const
Definition: field_table.h:50

◆ Capacity()

intptr_t dart::FieldTable::Capacity ( ) const
inline

Definition at line 41 of file field_table.h.

41{ return capacity_; }

◆ Clone()

FieldTable * dart::FieldTable::Clone ( Isolate for_isolate,
IsolateGroup for_isolate_group = nullptr 
)

Definition at line 134 of file field_table.cc.

135 {
137 IsolateGroup::Current()->program_lock()->IsCurrentThreadReader());
138
139 FieldTable* clone = new FieldTable(for_isolate, for_isolate_group);
140 ASSERT(clone->table_ == nullptr);
141 if (table_ == nullptr) {
142 ASSERT(capacity_ == 0);
143 ASSERT(top_ == 0);
144 ASSERT(free_head_ == -1);
145 } else {
146 auto new_table = static_cast<ObjectPtr*>(
147 malloc(capacity_ * sizeof(ObjectPtr))); // NOLINT
148 memmove(new_table, table_, capacity_ * sizeof(ObjectPtr));
149 clone->table_ = new_table;
150 clone->capacity_ = capacity_;
151 clone->top_ = top_;
152 clone->free_head_ = free_head_;
153 }
154 return clone;
155}
#define DEBUG_ASSERT(cond)
Definition: assert.h:321
FieldTable(Isolate *isolate, IsolateGroup *isolate_group=nullptr)
Definition: field_table.h:25
static IsolateGroup * Current()
Definition: isolate.h:539
void * malloc(size_t size)
Definition: allocation.cc:19

◆ FieldOffsetFor()

intptr_t dart::FieldTable::FieldOffsetFor ( intptr_t  field_id)
static

Definition at line 51 of file field_table.cc.

51 {
52 return field_id * sizeof(ObjectPtr); // NOLINT
53}

◆ Free()

void dart::FieldTable::Free ( intptr_t  index)

Definition at line 86 of file field_table.cc.

86 {
87 table_[field_id] = Smi::New(free_head_);
88 free_head_ = field_id;
89}
static SmiPtr New(intptr_t value)
Definition: object.h:10006

◆ FreeOldTables()

void dart::FieldTable::FreeOldTables ( )

Definition at line 45 of file field_table.cc.

45 {
46 while (old_tables_->length() > 0) {
47 free(old_tables_->RemoveLast());
48 }
49}

◆ IsReadyToUse()

bool dart::FieldTable::IsReadyToUse ( ) const

Definition at line 25 of file field_table.cc.

25 {
27 IsolateGroup::Current()->IsReloading() ||
28 IsolateGroup::Current()->program_lock()->IsCurrentThreadReader());
29 return is_ready_to_use_;
30}

◆ IsValidIndex()

bool dart::FieldTable::IsValidIndex ( intptr_t  index) const
inline

Definition at line 50 of file field_table.h.

50{ return index >= 0 && index < top_; }

◆ MarkReadyToUse()

void dart::FieldTable::MarkReadyToUse ( )

Definition at line 32 of file field_table.cc.

32 {
33 // The isolate will mark it's field table ready-to-use upon initialization of
34 // the isolate. Only after it was marked as ready-to-use will it participate
35 // in new static field registrations.
36 //
37 // By requiring a read lock here we ensure no other thread is is registering a
38 // new static field at this moment (it would need exclusive writer lock).
40 IsolateGroup::Current()->program_lock()->IsCurrentThreadReader());
41 ASSERT(!is_ready_to_use_);
42 is_ready_to_use_ = true;
43}

◆ NumFieldIds()

intptr_t dart::FieldTable::NumFieldIds ( ) const
inline

Definition at line 40 of file field_table.h.

40{ return top_; }

◆ Register()

bool dart::FieldTable::Register ( const Field field,
intptr_t  expected_field_id = -1 
)

Definition at line 55 of file field_table.cc.

55 {
57 IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
58 ASSERT(is_ready_to_use_);
59
60 if (free_head_ < 0) {
61 bool grown_backing_store = false;
62 if (top_ == capacity_) {
63 const intptr_t new_capacity = capacity_ + kCapacityIncrement;
64 Grow(new_capacity);
65 grown_backing_store = true;
66 }
67
68 ASSERT(top_ < capacity_);
69 ASSERT(expected_field_id == -1 || expected_field_id == top_);
70 field.set_field_id(top_);
71 table_[top_] = Object::sentinel().ptr();
72
73 ++top_;
74 return grown_backing_store;
75 }
76
77 // Reuse existing free element. This is "slow path" that should only be
78 // triggered after hot reload.
79 intptr_t reused_free = free_head_;
80 free_head_ = Smi::Value(Smi::RawCast(table_[free_head_]));
81 field.set_field_id(reused_free);
82 table_[reused_free] = Object::sentinel().ptr();
83 return false;
84}
static ObjectPtr RawCast(ObjectPtr obj)
Definition: object.h:325
intptr_t Value() const
Definition: object.h:9990

◆ SetAt()

void dart::FieldTable::SetAt ( intptr_t  index,
ObjectPtr  raw_instance,
bool  concurrent_use = false 
)
inline

Definition at line 76 of file field_table.h.

78 {
79 ASSERT(index < capacity_);
80 ObjectPtr* slot = &table_[index];
81 if (concurrent_use) {
82 reinterpret_cast<AcqRelAtomic<ObjectPtr>*>(slot)->store(raw_instance);
83 } else {
84 // There is no concurrent access expected for this field, so we avoid
85 // using atomics. This will allow us to detect via TSAN if there are
86 // racy uses.
87 *slot = raw_instance;
88 }
89 }
SI void store(P *ptr, const T &val)

◆ table()

ObjectPtr * dart::FieldTable::table ( )
inline

Definition at line 43 of file field_table.h.

43{ return table_; }

◆ VisitObjectPointers()

void dart::FieldTable::VisitObjectPointers ( ObjectPointerVisitor visitor)

Definition at line 157 of file field_table.cc.

157 {
158 // GC might try to visit field table before it's isolate done setting it up.
159 if (table_ == nullptr) {
160 return;
161 }
162
163 ASSERT(visitor != nullptr);
164 visitor->set_gc_root_type("static fields table");
165 visitor->VisitPointers(&table_[0], &table_[top_ - 1]);
166 visitor->clear_gc_root_type();
167}

Member Data Documentation

◆ kCapacityIncrement

constexpr int dart::FieldTable::kCapacityIncrement = 256
staticconstexpr

Definition at line 97 of file field_table.h.

◆ kInitialCapacity

constexpr int dart::FieldTable::kInitialCapacity = 512
staticconstexpr

Definition at line 96 of file field_table.h.


The documentation for this class was generated from the following files: