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

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
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 UpdateExternalNewSpaceBit();
219 // TODO(koda): On repeated/large external allocations for existing objects, 221 // TODO(koda): On repeated/large external allocations for existing objects,
220 // without any intervening normal allocation, GC will not trigger. 222 // without any intervening normal allocation, GC will not trigger.
221 isolate->heap()->AllocateExternal(external_size_, SpaceForExternal()); 223 isolate->heap()->AllocateExternal(external_size(), SpaceForExternal());
222 } 224 }
223 225
224 // Called when the referent becomes unreachable. 226 // Called when the referent becomes unreachable.
225 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) { 227 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) {
226 EnsureFreeExternal(isolate); 228 EnsureFreeExternal(isolate);
227 Finalize(isolate, this, is_prologue_weak); 229 Finalize(isolate, this, is_prologue_weak);
228 } 230 }
229 231
230 // Called when the referent has moved, potentially between generations. 232 // Called when the referent has moved, potentially between generations.
231 void UpdateRelocated(Heap::Space before, Isolate* isolate) { 233 void UpdateRelocated(Isolate* isolate) {
232 isolate->heap()->FreeExternal(external_size_, before); 234 Heap::Space after = SpaceForExternal();
233 isolate->heap()->AllocateExternal(external_size_, SpaceForExternal()); 235 Heap::Space before = WasPromotedSinceLastCall() ? Heap::kNew : after;
siva 2014/03/11 16:35:01 Since we only promote new to old why can't this ch
koda 2014/03/11 17:35:45 Done. My reasoning was to localize the assumption
236 isolate->heap()->FreeExternal(external_size(), before);
237 isolate->heap()->AllocateExternal(external_size(), after);
siva 2014/03/11 16:35:01 if before == after it not necessary to do this Fre
koda 2014/03/11 17:35:45 Done.
234 } 238 }
235 239
236 // Idempotent. Called when the handle is explicitly deleted or the 240 // Idempotent. Called when the handle is explicitly deleted or the
237 // referent becomes unreachable. 241 // referent becomes unreachable.
238 void EnsureFreeExternal(Isolate* isolate) { 242 void EnsureFreeExternal(Isolate* isolate) {
239 isolate->heap()->FreeExternal(external_size_, SpaceForExternal()); 243 isolate->heap()->FreeExternal(external_size(), SpaceForExternal());
240 external_size_ = 0; 244 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 } 245 }
249 246
250 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) { 247 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) {
251 uword addr = reinterpret_cast<uword>(handle); 248 uword addr = reinterpret_cast<uword>(handle);
252 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag; 249 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag;
253 } 250 }
254 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); 251 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle);
255 252
256 private: 253 private:
257 enum { 254 enum {
258 kWeakPersistentTag = 0, 255 kWeakPersistentTag = 0,
259 kPrologueWeakPersistentTag = 1, 256 kPrologueWeakPersistentTag = 1,
260 kWeakPersistentTagSize = 1, 257 kWeakPersistentTagSize = 1,
261 kWeakPersistentTagMask = 1, 258 kWeakPersistentTagMask = 1,
262 }; 259 };
263 260
261 // This part of external_data_ is the number of externally allocated bytes.
262 // TODO(koda): Measure size in words instead.
263 class ExternalSizeBits : public BitField<intptr_t, 1, kBitsPerWord - 1> {};
264 // This bit of external_data_ is true if the referent was created in new
265 // space and WasPromotedSinceLastCall has not yet detected any promotion.
266 class ExternalNewSpaceBit : public BitField<bool, 0, 1> {};
267 // TODO(koda): Use bitfield also for the prologue tag.
268
264 friend class FinalizablePersistentHandles; 269 friend class FinalizablePersistentHandles;
265 270
266 FinalizablePersistentHandle() 271 FinalizablePersistentHandle()
267 : raw_(NULL), 272 : raw_(NULL),
268 peer_(NULL), 273 peer_(NULL),
269 external_size_(0), 274 external_data_(0),
270 callback_(NULL) { } 275 callback_(NULL) { }
271 ~FinalizablePersistentHandle() { } 276 ~FinalizablePersistentHandle() { }
272 277
273 static void Finalize(Isolate* isolate, 278 static void Finalize(Isolate* isolate,
274 FinalizablePersistentHandle* handle, 279 FinalizablePersistentHandle* handle,
275 bool is_prologue_weak) { 280 bool is_prologue_weak) {
276 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); 281 Dart_WeakPersistentHandleFinalizer callback = handle->callback();
277 if (callback != NULL) { 282 if (callback != NULL) {
278 void* peer = handle->peer(); 283 void* peer = handle->peer();
279 handle->Clear(); 284 handle->Clear();
(...skipping 16 matching lines...) Expand all
296 ASSERT(!raw_->IsHeapObject()); 301 ASSERT(!raw_->IsHeapObject());
297 } 302 }
298 void FreeHandle(FinalizablePersistentHandle* free_list) { 303 void FreeHandle(FinalizablePersistentHandle* free_list) {
299 Clear(); 304 Clear();
300 SetNext(free_list); 305 SetNext(free_list);
301 } 306 }
302 307
303 void Clear() { 308 void Clear() {
304 raw_ = Object::null(); 309 raw_ = Object::null();
305 peer_ = NULL; 310 peer_ = NULL;
306 external_size_ = 0; 311 external_data_ = 0;
307 callback_ = NULL; 312 callback_ = NULL;
308 } 313 }
309 314
315 intptr_t external_size() const {
316 return ExternalSizeBits::decode(external_data_);
317 }
318
319 void set_external_size(intptr_t size) {
320 external_data_ = ExternalSizeBits::update(size, external_data_);
321 }
322
323 void UpdateExternalNewSpaceBit() {
324 bool value = (SpaceForExternal() == Heap::kNew);
325 external_data_ = ExternalNewSpaceBit::update(value, external_data_);
326 }
siva 2014/03/11 16:35:01 The use of UpdateExternalNewSpaceBit to both set a
koda 2014/03/11 17:35:45 Done.
327
328 bool WasPromotedSinceLastCall() {
329 if (ExternalNewSpaceBit::decode(external_data_) &&
330 SpaceForExternal() == Heap::kOld) {
331 UpdateExternalNewSpaceBit();
332 return true;
333 } else {
334 return false;
335 }
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

Powered by Google App Engine
This is Rietveld 408576698