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

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

Issue 1173043002: Reuse empty StoreBufferBlocks. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address comments Created 5 years, 6 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 class StoreBufferBlock { 19 class StoreBufferBlock {
19 public: 20 public:
20 // Each full block contains kSize pointers. 21 // Each full block contains kSize pointers.
21 static const int32_t kSize = 1024; 22 static const int32_t kSize = 1024;
22 23
23 void Reset() { top_ = 0; } 24 void Reset() {
25 top_ = 0;
26 next_ = NULL;
27 }
24 28
25 // TODO(koda): Make private after adding visitor interface to StoreBuffer.
26 StoreBufferBlock* next() const { return next_; } 29 StoreBufferBlock* next() const { return next_; }
27 30
28 intptr_t Count() const { return top_; } 31 intptr_t Count() const { return top_; }
29 bool IsFull() const { return Count() == kSize; } 32 bool IsFull() const { return Count() == kSize; }
33 bool IsEmpty() const { return Count() == 0; }
30 34
31 void Add(RawObject* obj) { 35 void Push(RawObject* obj) {
32 ASSERT(!IsFull()); 36 ASSERT(!IsFull());
33 pointers_[top_++] = obj; 37 pointers_[top_++] = obj;
34 } 38 }
35 39
36 RawObject* At(intptr_t i) const { 40 RawObject* Pop() {
37 ASSERT(i >= 0); 41 ASSERT(!IsEmpty());
38 ASSERT(i < top_); 42 return pointers_[--top_];
39 return pointers_[i];
40 } 43 }
41 44
42 #if defined(TESTING) 45 #if defined(TESTING)
43 bool Contains(RawObject* obj) const { 46 bool Contains(RawObject* obj) const {
44 for (intptr_t i = 0; i < Count(); i++) { 47 for (intptr_t i = 0; i < Count(); i++) {
45 if (At(i) == obj) { 48 if (pointers_[i] == obj) {
46 return true; 49 return true;
47 } 50 }
48 } 51 }
49 return false; 52 return false;
50 } 53 }
51 #endif // TESTING 54 #endif // TESTING
52 55
53 static intptr_t top_offset() { return OFFSET_OF(StoreBufferBlock, top_); } 56 static intptr_t top_offset() { return OFFSET_OF(StoreBufferBlock, top_); }
54 static intptr_t pointers_offset() { 57 static intptr_t pointers_offset() {
55 return OFFSET_OF(StoreBufferBlock, pointers_); 58 return OFFSET_OF(StoreBufferBlock, pointers_);
56 } 59 }
57 60
58 private: 61 private:
59 StoreBufferBlock() : next_(NULL), top_(0) {} 62 StoreBufferBlock() : next_(NULL), top_(0) {}
63 ~StoreBufferBlock() {
64 ASSERT(IsEmpty()); // Guard against unintentionally discarding pointers.
65 }
60 66
61 StoreBufferBlock* next_; 67 StoreBufferBlock* next_;
62 int32_t top_; 68 int32_t top_;
63 RawObject* pointers_[kSize]; 69 RawObject* pointers_[kSize];
64 70
65 friend class StoreBuffer; 71 friend class StoreBuffer;
66 72
67 DISALLOW_COPY_AND_ASSIGN(StoreBufferBlock); 73 DISALLOW_COPY_AND_ASSIGN(StoreBufferBlock);
68 }; 74 };
69 75
70 76
71 class StoreBuffer { 77 class StoreBuffer {
72 public: 78 public:
73 StoreBuffer(); 79 StoreBuffer();
74 ~StoreBuffer(); 80 ~StoreBuffer();
81 static void InitOnce();
82
83 // Interrupt when crossing this threshold of non-empty blocks in the buffer.
84 static const intptr_t kMaxNonEmpty = 100;
75 85
76 // Adds and transfers ownership of the block to the buffer. 86 // Adds and transfers ownership of the block to the buffer.
77 void PushBlock(StoreBufferBlock* block, bool check_threshold = true); 87 void PushBlock(StoreBufferBlock* block, bool check_threshold = true);
78 // Partially filled blocks can be reused, and there is an "inifite" supply 88 // Partially filled blocks can be reused, and there is an "inifite" supply
79 // of empty blocks (reused or newly allocated). In any case, the caller 89 // of empty blocks (reused or newly allocated). In any case, the caller
80 // takes ownership of the returned block. 90 // takes ownership of the returned block.
81 StoreBufferBlock* PopBlock(); 91 StoreBufferBlock* PopBlock();
82 StoreBufferBlock* PopEmptyBlock(); 92 StoreBufferBlock* PopEmptyBlock();
83 93
84 // 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).
85 // TODO(koda): Replace with VisitObjectPointers.
86 StoreBufferBlock* Blocks(); 95 StoreBufferBlock* Blocks();
87 96
88 // Discards the contents of this store buffer. 97 // Discards the contents of this store buffer.
89 void Reset(); 98 void Reset();
90 99
91 private: 100 private:
92 class List { 101 class List {
93 public: 102 public:
94 List() : head_(NULL), length_(0) {} 103 List() : head_(NULL), length_(0) {}
95 ~List(); 104 ~List();
96 void Push(StoreBufferBlock* block); 105 void Push(StoreBufferBlock* block);
97 StoreBufferBlock* Pop(); 106 StoreBufferBlock* Pop();
98 intptr_t length() const { return length_; } 107 intptr_t length() const { return length_; }
99 bool IsEmpty() const { return head_ == NULL; } 108 bool IsEmpty() const { return head_ == NULL; }
100 StoreBufferBlock* PopAll(); 109 StoreBufferBlock* PopAll();
101 private: 110 private:
102 StoreBufferBlock* head_; 111 StoreBufferBlock* head_;
103 intptr_t length_; 112 intptr_t length_;
104 DISALLOW_COPY_AND_ASSIGN(List); 113 DISALLOW_COPY_AND_ASSIGN(List);
105 }; 114 };
106 115
107 // Check if we run over the max number of deduplication sets. 116 // Check if we run over the max number of deduplication sets.
108 // If we did schedule an interrupt. 117 // If we did schedule an interrupt.
109 void CheckThreshold(); 118 void CheckThresholdNonEmpty();
119
120 // If needed, trims the the global cache of empty blocks.
121 static void TrimGlobalEmpty();
110 122
111 List full_; 123 List full_;
112 List partial_; 124 List partial_;
113 // TODO(koda): static List empty_
114 Mutex* mutex_; 125 Mutex* mutex_;
115 126
127 static const intptr_t kMaxGlobalEmpty = 100;
128 static List* global_empty_;
129 static Mutex* global_mutex_;
130
116 DISALLOW_COPY_AND_ASSIGN(StoreBuffer); 131 DISALLOW_COPY_AND_ASSIGN(StoreBuffer);
117 }; 132 };
118 133
119 } // namespace dart 134 } // namespace dart
120 135
121 #endif // VM_STORE_BUFFER_H_ 136 #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