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

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

Issue 193473002: Fix external size accounting for prologue weak persistent handles. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/scavenger.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_DART_API_STATE_H_ 5 #ifndef VM_DART_API_STATE_H_
6 #define VM_DART_API_STATE_H_ 6 #define VM_DART_API_STATE_H_
7 7
8 #include "include/dart_api.h" 8 #include "include/dart_api.h"
9 9
10 #include "platform/thread.h" 10 #include "platform/thread.h"
11 #include "platform/utils.h" 11 #include "platform/utils.h"
12 #include "vm/bitfield.h"
12 #include "vm/dart_api_impl.h" 13 #include "vm/dart_api_impl.h"
13 #include "vm/flags.h" 14 #include "vm/flags.h"
14 #include "vm/growable_array.h" 15 #include "vm/growable_array.h"
15 #include "vm/handles.h" 16 #include "vm/handles.h"
16 #include "vm/object.h" 17 #include "vm/object.h"
17 #include "vm/os.h" 18 #include "vm/os.h"
18 #include "vm/raw_object.h" 19 #include "vm/raw_object.h"
19 #include "vm/visitor.h" 20 #include "vm/visitor.h"
20 21
21 #include "vm/handles_impl.h" 22 #include "vm/handles_impl.h"
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 uword addr = reinterpret_cast<uword>(this); 209 uword addr = reinterpret_cast<uword>(this);
209 return reinterpret_cast<Dart_WeakPersistentHandle>( 210 return reinterpret_cast<Dart_WeakPersistentHandle>(
210 addr | kPrologueWeakPersistentTag); 211 addr | kPrologueWeakPersistentTag);
211 } 212 }
212 Dart_WeakPersistentHandle apiHandle() { 213 Dart_WeakPersistentHandle apiHandle() {
213 return reinterpret_cast<Dart_WeakPersistentHandle>(this); 214 return reinterpret_cast<Dart_WeakPersistentHandle>(this);
214 } 215 }
215 216
216 void SetExternalSize(intptr_t size, Isolate* isolate) { 217 void SetExternalSize(intptr_t size, Isolate* isolate) {
217 ASSERT(size >= 0); 218 ASSERT(size >= 0);
218 external_size_ = Utils::RoundUp(size, kObjectAlignment); 219 set_external_size(Utils::RoundUp(size, kObjectAlignment));
220 if (SpaceForExternal() == Heap::kNew) {
221 SetExternalNewSpaceBit();
222 }
219 // TODO(koda): On repeated/large external allocations for existing objects, 223 // TODO(koda): On repeated/large external allocations for existing objects,
220 // without any intervening normal allocation, GC will not trigger. 224 // without any intervening normal allocation, GC will not trigger.
221 isolate->heap()->AllocateExternal(external_size_, SpaceForExternal()); 225 isolate->heap()->AllocateExternal(external_size(), SpaceForExternal());
222 } 226 }
223 227
224 // Called when the referent becomes unreachable. 228 // Called when the referent becomes unreachable.
225 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) { 229 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) {
226 EnsureFreeExternal(isolate); 230 EnsureFreeExternal(isolate);
227 Finalize(isolate, this, is_prologue_weak); 231 Finalize(isolate, this, is_prologue_weak);
228 } 232 }
229 233
230 // Called when the referent has moved, potentially between generations. 234 // Called when the referent has moved, potentially between generations.
231 void UpdateRelocated(Heap::Space before, Isolate* isolate) { 235 void UpdateRelocated(Isolate* isolate) {
232 isolate->heap()->FreeExternal(external_size_, before); 236 if (IsSetNewSpaceBit() && (SpaceForExternal() == Heap::kOld)) {
233 isolate->heap()->AllocateExternal(external_size_, SpaceForExternal()); 237 isolate->heap()->FreeExternal(external_size(), Heap::kNew);
238 isolate->heap()->AllocateExternal(external_size(), Heap::kOld);
239 ClearExternalNewSpaceBit();
240 }
234 } 241 }
235 242
236 // Idempotent. Called when the handle is explicitly deleted or the 243 // Idempotent. Called when the handle is explicitly deleted or the
237 // referent becomes unreachable. 244 // referent becomes unreachable.
238 void EnsureFreeExternal(Isolate* isolate) { 245 void EnsureFreeExternal(Isolate* isolate) {
239 isolate->heap()->FreeExternal(external_size_, SpaceForExternal()); 246 isolate->heap()->FreeExternal(external_size(), SpaceForExternal());
240 external_size_ = 0; 247 set_external_size(0);
241 }
242
243 // Returns the space to charge for the external size.
244 Heap::Space SpaceForExternal() const {
245 // Non-heap and VM-heap objects count as old space here.
246 return (raw_->IsHeapObject() && raw_->IsNewObject()) ?
247 Heap::kNew : Heap::kOld;
248 } 248 }
249 249
250 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) { 250 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) {
251 uword addr = reinterpret_cast<uword>(handle); 251 uword addr = reinterpret_cast<uword>(handle);
252 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag; 252 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag;
253 } 253 }
254 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); 254 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle);
255 255
256 private: 256 private:
257 enum { 257 enum {
258 kWeakPersistentTag = 0, 258 kWeakPersistentTag = 0,
259 kPrologueWeakPersistentTag = 1, 259 kPrologueWeakPersistentTag = 1,
260 kWeakPersistentTagSize = 1, 260 kWeakPersistentTagSize = 1,
261 kWeakPersistentTagMask = 1, 261 kWeakPersistentTagMask = 1,
262 }; 262 };
263 263
264 // This part of external_data_ is the number of externally allocated bytes.
265 // TODO(koda): Measure size in words instead.
266 class ExternalSizeBits : public BitField<intptr_t, 1, kBitsPerWord - 1> {};
267 // This bit of external_data_ is true if the referent was created in new
268 // space and UpdateRelocated has not yet detected any promotion.
269 class ExternalNewSpaceBit : public BitField<bool, 0, 1> {};
270 // TODO(koda): Use bitfield also for the prologue tag.
271
264 friend class FinalizablePersistentHandles; 272 friend class FinalizablePersistentHandles;
265 273
266 FinalizablePersistentHandle() 274 FinalizablePersistentHandle()
267 : raw_(NULL), 275 : raw_(NULL),
268 peer_(NULL), 276 peer_(NULL),
269 external_size_(0), 277 external_data_(0),
270 callback_(NULL) { } 278 callback_(NULL) { }
271 ~FinalizablePersistentHandle() { } 279 ~FinalizablePersistentHandle() { }
272 280
273 static void Finalize(Isolate* isolate, 281 static void Finalize(Isolate* isolate,
274 FinalizablePersistentHandle* handle, 282 FinalizablePersistentHandle* handle,
275 bool is_prologue_weak) { 283 bool is_prologue_weak) {
276 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); 284 Dart_WeakPersistentHandleFinalizer callback = handle->callback();
277 if (callback != NULL) { 285 if (callback != NULL) {
278 void* peer = handle->peer(); 286 void* peer = handle->peer();
279 handle->Clear(); 287 handle->Clear();
(...skipping 16 matching lines...) Expand all
296 ASSERT(!raw_->IsHeapObject()); 304 ASSERT(!raw_->IsHeapObject());
297 } 305 }
298 void FreeHandle(FinalizablePersistentHandle* free_list) { 306 void FreeHandle(FinalizablePersistentHandle* free_list) {
299 Clear(); 307 Clear();
300 SetNext(free_list); 308 SetNext(free_list);
301 } 309 }
302 310
303 void Clear() { 311 void Clear() {
304 raw_ = Object::null(); 312 raw_ = Object::null();
305 peer_ = NULL; 313 peer_ = NULL;
306 external_size_ = 0; 314 external_data_ = 0;
307 callback_ = NULL; 315 callback_ = NULL;
308 } 316 }
309 317
318 intptr_t external_size() const {
319 return ExternalSizeBits::decode(external_data_);
320 }
321
322 void set_external_size(intptr_t size) {
323 external_data_ = ExternalSizeBits::update(size, external_data_);
324 }
325
326 bool IsSetNewSpaceBit() const {
327 return ExternalNewSpaceBit::decode(external_data_);
328 }
329
330 void SetExternalNewSpaceBit() {
331 external_data_ = ExternalNewSpaceBit::update(true, external_data_);
332 }
333
334 void ClearExternalNewSpaceBit() {
335 external_data_ = ExternalNewSpaceBit::update(false, external_data_);
336 }
337
338 // Returns the space to charge for the external size.
339 Heap::Space SpaceForExternal() const {
340 // Non-heap and VM-heap objects count as old space here.
341 return (raw_->IsHeapObject() && raw_->IsNewObject()) ?
342 Heap::kNew : Heap::kOld;
343 }
344
310 RawObject* raw_; 345 RawObject* raw_;
311 void* peer_; 346 void* peer_;
312 intptr_t external_size_; 347 uword external_data_;
313 Dart_WeakPersistentHandleFinalizer callback_; 348 Dart_WeakPersistentHandleFinalizer callback_;
314 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. 349 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
315 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle); 350 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle);
316 }; 351 };
317 352
318 353
319 // Local handles repository structure. 354 // Local handles repository structure.
320 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; 355 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize;
321 static const int kLocalHandlesPerChunk = 64; 356 static const int kLocalHandlesPerChunk = 64;
322 static const int kOffsetOfRawPtrInLocalHandle = 0; 357 static const int kOffsetOfRawPtrInLocalHandle = 0;
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 ApiNativeScope::Current()->zone()) {} 893 ApiNativeScope::Current()->zone()) {}
859 ApiGrowableArray() 894 ApiGrowableArray()
860 : BaseGrowableArray<T, ValueObject>( 895 : BaseGrowableArray<T, ValueObject>(
861 ApiNativeScope::Current()->zone()) {} 896 ApiNativeScope::Current()->zone()) {}
862 }; 897 };
863 898
864 899
865 } // namespace dart 900 } // namespace dart
866 901
867 #endif // VM_DART_API_STATE_H_ 902 #endif // VM_DART_API_STATE_H_
OLDNEW
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/scavenger.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698