Flutter Engine
The Flutter Engine
field_table.h
Go to the documentation of this file.
1// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_FIELD_TABLE_H_
6#define RUNTIME_VM_FIELD_TABLE_H_
7
8#include "platform/assert.h"
9#include "platform/atomic.h"
10
11#include "vm/bitfield.h"
12#include "vm/class_id.h"
13#include "vm/globals.h"
14#include "vm/growable_array.h"
15#include "vm/tagged_pointer.h"
16
17namespace dart {
18
19class Isolate;
20class Field;
21class FieldInvalidator;
22
24 public:
25 explicit FieldTable(Isolate* isolate, IsolateGroup* isolate_group = nullptr)
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) {}
34
36
37 bool IsReadyToUse() const;
38 void MarkReadyToUse();
39
40 intptr_t NumFieldIds() const { return top_; }
41 intptr_t Capacity() const { return capacity_; }
42
43 ObjectPtr* table() { return table_; }
44
45 void FreeOldTables();
46
47 // Used by the generated code.
48 static intptr_t FieldOffsetFor(intptr_t field_id);
49
50 bool IsValidIndex(intptr_t index) const { return index >= 0 && index < top_; }
51
52 // Returns whether registering this field caused a growth in the backing
53 // store.
54 bool Register(const Field& field, intptr_t expected_field_id = -1);
55 void AllocateIndex(intptr_t index);
56
57 // Static field elements are being freed only during isolate reload
58 // when initially created static field have to get remapped to point
59 // to an existing static field value.
60 void Free(intptr_t index);
61
62 ObjectPtr At(intptr_t index, bool concurrent_use = false) const {
63 ASSERT(IsValidIndex(index));
64 if (concurrent_use) {
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 }
75
76 void SetAt(intptr_t index,
77 ObjectPtr raw_instance,
78 bool concurrent_use = false) {
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 }
90
91 FieldTable* Clone(Isolate* for_isolate,
92 IsolateGroup* for_isolate_group = nullptr);
93
95
96 static constexpr int kInitialCapacity = 512;
97 static constexpr int kCapacityIncrement = 256;
98
99 private:
100 void Grow(intptr_t new_capacity);
101
102 intptr_t top_;
103 intptr_t capacity_;
104 // -1 if free list is empty, otherwise index of first empty element. Empty
105 // elements are organized into linked list - they contain index of next
106 // element, last element contains -1.
107 intptr_t free_head_;
108
109 ObjectPtr* table_;
110 // When table_ grows and have to reallocated, keep the old one here
111 // so it will get freed when its are no longer in use.
113
114 // If non-null, it will specify the isolate this field table belongs to.
115 // Growing the field table will keep the cached field table on the isolate's
116 // mutator thread up-to-date.
117 Isolate* isolate_;
118 IsolateGroup* isolate_group_;
119
120 // Whether this field table is ready to use by e.g. registering new static
121 // fields.
122 bool is_ready_to_use_ = false;
123
124 DISALLOW_COPY_AND_ASSIGN(FieldTable);
125};
126
127} // namespace dart
128
129#endif // RUNTIME_VM_FIELD_TABLE_H_
SI void store(P *ptr, const T &val)
SI T load(const P *ptr)
Definition: Transform_inl.h:98
static constexpr int kInitialCapacity
Definition: field_table.h:96
void FreeOldTables()
Definition: field_table.cc:45
bool Register(const Field &field, intptr_t expected_field_id=-1)
Definition: field_table.cc:55
void Free(intptr_t index)
Definition: field_table.cc:86
void SetAt(intptr_t index, ObjectPtr raw_instance, bool concurrent_use=false)
Definition: field_table.h:76
ObjectPtr At(intptr_t index, bool concurrent_use=false) const
Definition: field_table.h:62
void AllocateIndex(intptr_t index)
Definition: field_table.cc:91
bool IsReadyToUse() const
Definition: field_table.cc:25
ObjectPtr * table()
Definition: field_table.h:43
intptr_t NumFieldIds() const
Definition: field_table.h:40
bool IsValidIndex(intptr_t index) const
Definition: field_table.h:50
static constexpr int kCapacityIncrement
Definition: field_table.h:97
static intptr_t FieldOffsetFor(intptr_t field_id)
Definition: field_table.cc:51
intptr_t Capacity() const
Definition: field_table.h:41
void MarkReadyToUse()
Definition: field_table.cc:32
FieldTable * Clone(Isolate *for_isolate, IsolateGroup *for_isolate_group=nullptr)
Definition: field_table.cc:134
FieldTable(Isolate *isolate, IsolateGroup *isolate_group=nullptr)
Definition: field_table.h:25
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: field_table.cc:157
#define ASSERT(E)
Definition: dart_vm.cc:33