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

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

Issue 208443002: Use a bit in the handle structure to indicate if it is a prologue weak handle instead of the taggin… (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.cc ('k') | runtime/vm/gc_marker.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"
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 RawObject** raw_addr() { return &raw_; } 198 RawObject** raw_addr() { return &raw_; }
199 static intptr_t raw_offset() { 199 static intptr_t raw_offset() {
200 return OFFSET_OF(FinalizablePersistentHandle, raw_); 200 return OFFSET_OF(FinalizablePersistentHandle, raw_);
201 } 201 }
202 void* peer() const { return peer_; } 202 void* peer() const { return peer_; }
203 void set_peer(void* peer) { peer_ = peer; } 203 void set_peer(void* peer) { peer_ = peer; }
204 Dart_WeakPersistentHandleFinalizer callback() const { return callback_; } 204 Dart_WeakPersistentHandleFinalizer callback() const { return callback_; }
205 void set_callback(Dart_WeakPersistentHandleFinalizer callback) { 205 void set_callback(Dart_WeakPersistentHandleFinalizer callback) {
206 callback_ = callback; 206 callback_ = callback;
207 } 207 }
208 Dart_WeakPersistentHandle apiPrologueHandle() {
209 uword addr = reinterpret_cast<uword>(this);
210 return reinterpret_cast<Dart_WeakPersistentHandle>(
211 addr | kPrologueWeakPersistentTag);
212 }
213 Dart_WeakPersistentHandle apiHandle() { 208 Dart_WeakPersistentHandle apiHandle() {
214 return reinterpret_cast<Dart_WeakPersistentHandle>(this); 209 return reinterpret_cast<Dart_WeakPersistentHandle>(this);
215 } 210 }
216 211
217 void SetExternalSize(intptr_t size, Isolate* isolate) { 212 void SetExternalSize(intptr_t size, Isolate* isolate) {
218 ASSERT(size >= 0); 213 ASSERT(size >= 0);
219 set_external_size(Utils::RoundUp(size, kObjectAlignment)); 214 set_external_size(Utils::RoundUp(size, kObjectAlignment));
220 if (SpaceForExternal() == Heap::kNew) { 215 if (SpaceForExternal() == Heap::kNew) {
221 SetExternalNewSpaceBit(); 216 SetExternalNewSpaceBit();
222 } 217 }
223 // TODO(koda): On repeated/large external allocations for existing objects, 218 // TODO(koda): On repeated/large external allocations for existing objects,
224 // without any intervening normal allocation, GC will not trigger. 219 // without any intervening normal allocation, GC will not trigger.
225 isolate->heap()->AllocateExternal(external_size(), SpaceForExternal()); 220 isolate->heap()->AllocateExternal(external_size(), SpaceForExternal());
226 } 221 }
227 222
228 // Called when the referent becomes unreachable. 223 // Called when the referent becomes unreachable.
229 void UpdateUnreachable(Isolate* isolate, bool is_prologue_weak) { 224 void UpdateUnreachable(Isolate* isolate) {
230 EnsureFreeExternal(isolate); 225 EnsureFreeExternal(isolate);
231 Finalize(isolate, this, is_prologue_weak); 226 Finalize(isolate, this);
232 } 227 }
233 228
234 // Called when the referent has moved, potentially between generations. 229 // Called when the referent has moved, potentially between generations.
235 void UpdateRelocated(Isolate* isolate) { 230 void UpdateRelocated(Isolate* isolate) {
236 if (IsSetNewSpaceBit() && (SpaceForExternal() == Heap::kOld)) { 231 if (IsSetNewSpaceBit() && (SpaceForExternal() == Heap::kOld)) {
237 isolate->heap()->FreeExternal(external_size(), Heap::kNew); 232 isolate->heap()->FreeExternal(external_size(), Heap::kNew);
238 isolate->heap()->AllocateExternal(external_size(), Heap::kOld); 233 isolate->heap()->AllocateExternal(external_size(), Heap::kOld);
239 ClearExternalNewSpaceBit(); 234 ClearExternalNewSpaceBit();
240 } 235 }
241 } 236 }
242 237
243 // Idempotent. Called when the handle is explicitly deleted or the 238 // Idempotent. Called when the handle is explicitly deleted or the
244 // referent becomes unreachable. 239 // referent becomes unreachable.
245 void EnsureFreeExternal(Isolate* isolate) { 240 void EnsureFreeExternal(Isolate* isolate) {
246 isolate->heap()->FreeExternal(external_size(), SpaceForExternal()); 241 isolate->heap()->FreeExternal(external_size(), SpaceForExternal());
247 set_external_size(0); 242 set_external_size(0);
248 } 243 }
249 244
250 static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) { 245 bool IsPrologueWeakPersistent() {
251 uword addr = reinterpret_cast<uword>(handle); 246 return PrologueWeakBit::decode(external_data_);
252 return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag;
253 } 247 }
248
249 void SetPrologueWeakPersistent(bool value) {
250 external_data_ = PrologueWeakBit::update(value, external_data_);
251 }
252
254 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); 253 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle);
255 254
256 private: 255 private:
257 enum { 256 enum {
258 kWeakPersistentTag = 0, 257 kExternalNewSpaceBit = 0,
259 kPrologueWeakPersistentTag = 1, 258 kPrologueWeakBit = 1,
260 kWeakPersistentTagSize = 1, 259 kExternalSizeBits = 2,
261 kWeakPersistentTagMask = 1, 260 kExternalSizeBitsSize = (kBitsPerWord - 2),
262 }; 261 };
263 262
264 // This part of external_data_ is the number of externally allocated bytes. 263 // This part of external_data_ is the number of externally allocated bytes.
265 // TODO(koda): Measure size in words instead. 264 // TODO(koda): Measure size in words instead.
266 class ExternalSizeBits : public BitField<intptr_t, 1, kBitsPerWord - 1> {}; 265 class ExternalSizeBits : public BitField<intptr_t,
266 kExternalSizeBits,
267 kExternalSizeBitsSize> {}; // NOLINT
267 // This bit of external_data_ is true if the referent was created in new 268 // 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 // space and UpdateRelocated has not yet detected any promotion.
269 class ExternalNewSpaceBit : public BitField<bool, 0, 1> {}; 270 class ExternalNewSpaceBit : public BitField<bool, kExternalNewSpaceBit, 1> {};
270 // TODO(koda): Use bitfield also for the prologue tag. 271 // This bit is used to indicate that it is a prologue weak persistent handle.
272 class PrologueWeakBit : public BitField<bool, kPrologueWeakBit, 1> {};
271 273
272 friend class FinalizablePersistentHandles; 274 friend class FinalizablePersistentHandles;
273 275
274 FinalizablePersistentHandle() 276 FinalizablePersistentHandle()
275 : raw_(NULL), 277 : raw_(NULL),
276 peer_(NULL), 278 peer_(NULL),
277 external_data_(0), 279 external_data_(0),
278 callback_(NULL) { } 280 callback_(NULL) { }
279 ~FinalizablePersistentHandle() { } 281 ~FinalizablePersistentHandle() { }
280 282
281 static void Finalize(Isolate* isolate, 283 static void Finalize(Isolate* isolate, FinalizablePersistentHandle* handle);
282 FinalizablePersistentHandle* handle,
283 bool is_prologue_weak);
284 284
285 // Overload the raw_ field as a next pointer when adding freed 285 // Overload the raw_ field as a next pointer when adding freed
286 // handles to the free list. 286 // handles to the free list.
287 FinalizablePersistentHandle* Next() { 287 FinalizablePersistentHandle* Next() {
288 return reinterpret_cast<FinalizablePersistentHandle*>(raw_); 288 return reinterpret_cast<FinalizablePersistentHandle*>(raw_);
289 } 289 }
290 void SetNext(FinalizablePersistentHandle* free_list) { 290 void SetNext(FinalizablePersistentHandle* free_list) {
291 raw_ = reinterpret_cast<RawObject*>(free_list); 291 raw_ = reinterpret_cast<RawObject*>(free_list);
292 ASSERT(!raw_->IsHeapObject()); 292 ASSERT(!raw_->IsHeapObject());
293 } 293 }
294 void FreeHandle(FinalizablePersistentHandle* free_list) { 294 void FreeHandle(FinalizablePersistentHandle* free_list) {
295 Clear(); 295 Clear();
296 SetNext(free_list); 296 SetNext(free_list);
297 } 297 }
298 298
299 void Clear() { 299 void Clear() {
300 raw_ = Object::null(); 300 raw_ = Object::null();
301 peer_ = NULL; 301 peer_ = NULL;
302 external_data_ = 0; 302 external_data_ = 0;
303 callback_ = NULL; 303 callback_ = NULL;
304 } 304 }
305 305
306 intptr_t external_size() const { 306 intptr_t external_size() const {
307 return ExternalSizeBits::decode(external_data_); 307 return ExternalSizeBits::decode(external_data_);
308 } 308 }
309 309
310 void set_external_size(intptr_t size) { 310 void set_external_size(intptr_t size) {
311 ASSERT(ExternalSizeBits::is_valid(size));
311 external_data_ = ExternalSizeBits::update(size, external_data_); 312 external_data_ = ExternalSizeBits::update(size, external_data_);
312 } 313 }
313 314
314 bool IsSetNewSpaceBit() const { 315 bool IsSetNewSpaceBit() const {
315 return ExternalNewSpaceBit::decode(external_data_); 316 return ExternalNewSpaceBit::decode(external_data_);
316 } 317 }
317 318
318 void SetExternalNewSpaceBit() { 319 void SetExternalNewSpaceBit() {
319 external_data_ = ExternalNewSpaceBit::update(true, external_data_); 320 external_data_ = ExternalNewSpaceBit::update(true, external_data_);
320 } 321 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 free_list_(NULL) { } 503 free_list_(NULL) { }
503 ~FinalizablePersistentHandles() { 504 ~FinalizablePersistentHandles() {
504 free_list_ = NULL; 505 free_list_ = NULL;
505 } 506 }
506 507
507 // Accessors. 508 // Accessors.
508 FinalizablePersistentHandle* free_list() const { return free_list_; } 509 FinalizablePersistentHandle* free_list() const { return free_list_; }
509 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; } 510 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; }
510 511
511 // Visit all handles stored in the various handle blocks. 512 // Visit all handles stored in the various handle blocks.
512 void VisitHandles(HandleVisitor* visitor, bool is_prologue_weak) { 513 void VisitHandles(HandleVisitor* visitor) {
513 Handles<kFinalizablePersistentHandleSizeInWords, 514 Handles<kFinalizablePersistentHandleSizeInWords,
514 kFinalizablePersistentHandlesPerChunk, 515 kFinalizablePersistentHandlesPerChunk,
515 kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit( 516 kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit(
516 visitor, is_prologue_weak); 517 visitor);
517 } 518 }
518 519
519 // Visit all object pointers stored in the various handles. 520 // Visit all object pointers stored in the various handles.
520 void VisitObjectPointers(ObjectPointerVisitor* visitor) { 521 void VisitObjectPointers(ObjectPointerVisitor* visitor) {
521 Handles<kFinalizablePersistentHandleSizeInWords, 522 Handles<kFinalizablePersistentHandleSizeInWords,
522 kFinalizablePersistentHandlesPerChunk, 523 kFinalizablePersistentHandlesPerChunk,
523 kOffsetOfRawPtrInFinalizablePersistentHandle>::VisitObjectPointers( 524 kOffsetOfRawPtrInFinalizablePersistentHandle>::VisitObjectPointers(
524 visitor); 525 visitor);
525 } 526 }
526 527
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 scope = scope->previous(); 745 scope = scope->previous();
745 } 746 }
746 persistent_handles().VisitObjectPointers(visitor); 747 persistent_handles().VisitObjectPointers(visitor);
747 if (visit_prologue_weak_handles) { 748 if (visit_prologue_weak_handles) {
748 prologue_weak_persistent_handles().VisitObjectPointers(visitor); 749 prologue_weak_persistent_handles().VisitObjectPointers(visitor);
749 } 750 }
750 } 751 }
751 752
752 void VisitWeakHandles(HandleVisitor* visitor, 753 void VisitWeakHandles(HandleVisitor* visitor,
753 bool visit_prologue_weak_handles) { 754 bool visit_prologue_weak_handles) {
754 weak_persistent_handles().VisitHandles(visitor, false); 755 weak_persistent_handles().VisitHandles(visitor);
755 if (visit_prologue_weak_handles) { 756 if (visit_prologue_weak_handles) {
756 prologue_weak_persistent_handles().VisitHandles(visitor, true); 757 prologue_weak_persistent_handles().VisitHandles(visitor);
757 } 758 }
758 } 759 }
759 760
760 bool IsValidLocalHandle(Dart_Handle object) const { 761 bool IsValidLocalHandle(Dart_Handle object) const {
761 ApiLocalScope* scope = top_scope_; 762 ApiLocalScope* scope = top_scope_;
762 while (scope != NULL) { 763 while (scope != NULL) {
763 if (scope->local_handles()->IsValidHandle(object)) { 764 if (scope->local_handles()->IsValidHandle(object)) {
764 return true; 765 return true;
765 } 766 }
766 scope = scope->previous(); 767 scope = scope->previous();
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 ApiNativeScope::Current()->zone()) {} 882 ApiNativeScope::Current()->zone()) {}
882 ApiGrowableArray() 883 ApiGrowableArray()
883 : BaseGrowableArray<T, ValueObject>( 884 : BaseGrowableArray<T, ValueObject>(
884 ApiNativeScope::Current()->zone()) {} 885 ApiNativeScope::Current()->zone()) {}
885 }; 886 };
886 887
887 888
888 } // namespace dart 889 } // namespace dart
889 890
890 #endif // VM_DART_API_STATE_H_ 891 #endif // VM_DART_API_STATE_H_
OLDNEW
« no previous file with comments | « runtime/vm/dart_api_impl.cc ('k') | runtime/vm/gc_marker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698