Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: runtime/vm/store_buffer.h

Issue 1350933004: Distinct block sizes for StoreBuffer/MarkingStack. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Ready for review. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/scavenger.cc ('k') | runtime/vm/store_buffer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_STORE_BUFFER_H_ 5 #ifndef VM_STORE_BUFFER_H_
6 #define VM_STORE_BUFFER_H_ 6 #define VM_STORE_BUFFER_H_
7 7
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/globals.h" 9 #include "vm/globals.h"
10 10
11 namespace dart { 11 namespace dart {
12 12
13 // Forward declarations. 13 // Forward declarations.
14 class Isolate; 14 class Isolate;
15 class Mutex; 15 class Mutex;
16 class RawObject; 16 class RawObject;
17 17
18 // A set of RawObject*. Must be emptied before destruction (using Pop/Reset). 18 // A set of RawObject*. Must be emptied before destruction (using Pop/Reset).
19 class StoreBufferBlock { 19 template<int Size>
20 class PointerBlock {
20 public: 21 public:
21 // Each full block contains kSize pointers. 22 enum { kSize = Size };
22 static const int32_t kSize = 1024;
23 23
24 void Reset() { 24 void Reset() {
25 top_ = 0; 25 top_ = 0;
26 next_ = NULL; 26 next_ = NULL;
27 } 27 }
28 28
29 StoreBufferBlock* next() const { return next_; } 29 PointerBlock<Size>* next() const { return next_; }
30 30
31 intptr_t Count() const { return top_; } 31 intptr_t Count() const { return top_; }
32 bool IsFull() const { return Count() == kSize; } 32 bool IsFull() const { return Count() == kSize; }
33 bool IsEmpty() const { return Count() == 0; } 33 bool IsEmpty() const { return Count() == 0; }
34 34
35 void Push(RawObject* obj) { 35 void Push(RawObject* obj) {
36 ASSERT(!IsFull()); 36 ASSERT(!IsFull());
37 pointers_[top_++] = obj; 37 pointers_[top_++] = obj;
38 } 38 }
39 39
40 RawObject* Pop() { 40 RawObject* Pop() {
41 ASSERT(!IsEmpty()); 41 ASSERT(!IsEmpty());
42 return pointers_[--top_]; 42 return pointers_[--top_];
43 } 43 }
44 44
45 #if defined(TESTING) 45 #if defined(TESTING)
46 bool Contains(RawObject* obj) const { 46 bool Contains(RawObject* obj) const {
47 for (intptr_t i = 0; i < Count(); i++) { 47 for (intptr_t i = 0; i < Count(); i++) {
48 if (pointers_[i] == obj) { 48 if (pointers_[i] == obj) {
49 return true; 49 return true;
50 } 50 }
51 } 51 }
52 return false; 52 return false;
53 } 53 }
54 #endif // TESTING 54 #endif // TESTING
55 55
56 static intptr_t top_offset() { return OFFSET_OF(StoreBufferBlock, top_); } 56 static intptr_t top_offset() { return OFFSET_OF(PointerBlock<Size>, top_); }
57 static intptr_t pointers_offset() { 57 static intptr_t pointers_offset() {
58 return OFFSET_OF(StoreBufferBlock, pointers_); 58 return OFFSET_OF(PointerBlock<Size>, pointers_);
59 } 59 }
60 60
61 private: 61 private:
62 StoreBufferBlock() : next_(NULL), top_(0) {} 62 PointerBlock() : next_(NULL), top_(0) {}
63 ~StoreBufferBlock() { 63 ~PointerBlock() {
64 ASSERT(IsEmpty()); // Guard against unintentionally discarding pointers. 64 ASSERT(IsEmpty()); // Guard against unintentionally discarding pointers.
65 } 65 }
66 66
67 StoreBufferBlock* next_; 67 PointerBlock<Size>* next_;
68 int32_t top_; 68 int32_t top_;
69 RawObject* pointers_[kSize]; 69 RawObject* pointers_[kSize];
70 70
71 friend class StoreBuffer; 71 template<int> friend class BlockStack;
72 72
73 DISALLOW_COPY_AND_ASSIGN(StoreBufferBlock); 73 DISALLOW_COPY_AND_ASSIGN(PointerBlock);
74 }; 74 };
75 75
76 76
77 class StoreBuffer { 77 template<int BlockSize>
78 class BlockStack {
78 public: 79 public:
79 StoreBuffer(); 80 typedef PointerBlock<BlockSize> Block;
80 ~StoreBuffer(); 81
82 BlockStack();
83 ~BlockStack();
81 static void InitOnce(); 84 static void InitOnce();
82 static void ShutDown(); 85 static void ShutDown();
83 86
84 // Interrupt when crossing this threshold of non-empty blocks in the buffer.
85 static const intptr_t kMaxNonEmpty = 100;
86
87 // Adds and transfers ownership of the block to the buffer.
88 void PushBlock(StoreBufferBlock* block, bool check_threshold = true);
89 // Partially filled blocks can be reused, and there is an "inifite" supply 87 // Partially filled blocks can be reused, and there is an "inifite" supply
90 // of empty blocks (reused or newly allocated). In any case, the caller 88 // of empty blocks (reused or newly allocated). In any case, the caller
91 // takes ownership of the returned block. 89 // takes ownership of the returned block.
92 StoreBufferBlock* PopNonFullBlock(); 90 Block* PopNonFullBlock();
93 StoreBufferBlock* PopEmptyBlock(); 91 Block* PopEmptyBlock();
94 StoreBufferBlock* PopNonEmptyBlock(); 92 Block* PopNonEmptyBlock();
95 93
96 // Pops and returns all non-empty blocks as a linked list (owned by caller). 94 // Pops and returns all non-empty blocks as a linked list (owned by caller).
97 StoreBufferBlock* Blocks(); 95 Block* Blocks();
98 96
99 // Discards the contents of this store buffer. 97 // Discards the contents of all non-empty blocks.
100 void Reset(); 98 void Reset();
101 99
102 // Check whether non-empty blocks have exceeded kMaxNonEmpty.
103 bool Overflowed();
104
105 bool IsEmpty(); 100 bool IsEmpty();
106 101
107 private: 102 protected:
108 class List { 103 class List {
109 public: 104 public:
110 List() : head_(NULL), length_(0) {} 105 List() : head_(NULL), length_(0) {}
111 ~List(); 106 ~List();
112 void Push(StoreBufferBlock* block); 107 void Push(Block* block);
113 StoreBufferBlock* Pop(); 108 Block* Pop();
114 intptr_t length() const { return length_; } 109 intptr_t length() const { return length_; }
115 bool IsEmpty() const { return head_ == NULL; } 110 bool IsEmpty() const { return head_ == NULL; }
116 StoreBufferBlock* PopAll(); 111 Block* PopAll();
117 private: 112 private:
118 StoreBufferBlock* head_; 113 Block* head_;
119 intptr_t length_; 114 intptr_t length_;
120 DISALLOW_COPY_AND_ASSIGN(List); 115 DISALLOW_COPY_AND_ASSIGN(List);
121 }; 116 };
122 117
118 // Adds and transfers ownership of the block to the buffer.
119 void PushBlockImpl(Block* block);
120
123 // If needed, trims the the global cache of empty blocks. 121 // If needed, trims the the global cache of empty blocks.
124 static void TrimGlobalEmpty(); 122 static void TrimGlobalEmpty();
125 123
126 List full_; 124 List full_;
127 List partial_; 125 List partial_;
128 Mutex* mutex_; 126 Mutex* mutex_;
129 127
130 static const intptr_t kMaxGlobalEmpty = 100; 128 static const intptr_t kMaxGlobalEmpty = 100;
131 static List* global_empty_; 129 static List* global_empty_;
132 static Mutex* global_mutex_; 130 static Mutex* global_mutex_;
Cutch 2015/09/17 18:04:06 Will it always be true that blocks of the same siz
koda 2015/09/17 19:13:18 Yes, the cache of empty blocks will be shared if w
133 131
134 DISALLOW_COPY_AND_ASSIGN(StoreBuffer); 132 private:
133 DISALLOW_COPY_AND_ASSIGN(BlockStack);
135 }; 134 };
136 135
136
137 static const int kStoreBufferBlockSize = 1024;
138 class StoreBuffer : public BlockStack<kStoreBufferBlockSize> {
139 public:
140 // Interrupt when crossing this threshold of non-empty blocks in the buffer.
141 static const intptr_t kMaxNonEmpty = 100;
142
143 // Adds and transfers ownership of the block to the buffer. Optionally
144 // checks the number of non-empty blocks for overflow, and schedules an
145 // interrupt on the current isolate if so.
146 void PushBlock(Block* block, bool check_threshold);
Cutch 2015/09/17 18:04:05 Instead of bool check_threshold could we have some
koda 2015/09/17 19:13:18 Done.
147
148 // Check whether non-empty blocks have exceeded kMaxNonEmpty (but takes no
149 // action).
150 bool Overflowed();
151 };
152
153
154 typedef StoreBuffer::Block StoreBufferBlock;
155
156
157 static const int kMarkingStackBlockSize = 64;
158 class MarkingStack : public BlockStack<kMarkingStackBlockSize> {
159 public:
160 // Adds and transfers ownership of the block to the buffer.
161 void PushBlock(Block* block) {
162 BlockStack<Block::kSize>::PushBlockImpl(block);
163 }
164 };
165
166
137 } // namespace dart 167 } // namespace dart
138 168
139 #endif // VM_STORE_BUFFER_H_ 169 #endif // VM_STORE_BUFFER_H_
OLDNEW
« no previous file with comments | « runtime/vm/scavenger.cc ('k') | runtime/vm/store_buffer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698