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

Side by Side Diff: include/v8.h

Issue 175503003: Add safe interface for collections of UniquePersistent (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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 | « no previous file | src/api.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 template<class F> friend class Handle; 405 template<class F> friend class Handle;
406 template<class F> friend class Local; 406 template<class F> friend class Local;
407 template<class F> friend class FunctionCallbackInfo; 407 template<class F> friend class FunctionCallbackInfo;
408 template<class F> friend class PropertyCallbackInfo; 408 template<class F> friend class PropertyCallbackInfo;
409 friend class String; 409 friend class String;
410 friend class Object; 410 friend class Object;
411 friend class Context; 411 friend class Context;
412 template<class F> friend class internal::CustomArguments; 412 template<class F> friend class internal::CustomArguments;
413 friend class HandleScope; 413 friend class HandleScope;
414 friend class EscapableHandleScope; 414 friend class EscapableHandleScope;
415 template<class F1, class F2, class F3> friend class PersistentValueMap;
415 416
416 V8_INLINE static Local<T> New(Isolate* isolate, T* that); 417 V8_INLINE static Local<T> New(Isolate* isolate, T* that);
417 }; 418 };
418 419
419 420
420 // Eternal handles are set-once handles that live for the life of the isolate. 421 // Eternal handles are set-once handles that live for the life of the isolate.
421 template <class T> class Eternal { 422 template <class T> class Eternal {
422 public: 423 public:
423 V8_INLINE Eternal() : index_(kInitialValue) { } 424 V8_INLINE Eternal() : index_(kInitialValue) { }
424 template<class S> 425 template<class S>
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 template<typename P> 521 template<typename P>
521 V8_INLINE void SetWeak( 522 V8_INLINE void SetWeak(
522 P* parameter, 523 P* parameter,
523 typename WeakCallbackData<T, P>::Callback callback); 524 typename WeakCallbackData<T, P>::Callback callback);
524 525
525 template<typename S, typename P> 526 template<typename S, typename P>
526 V8_INLINE void SetWeak( 527 V8_INLINE void SetWeak(
527 P* parameter, 528 P* parameter,
528 typename WeakCallbackData<S, P>::Callback callback); 529 typename WeakCallbackData<S, P>::Callback callback);
529 530
530 V8_INLINE void ClearWeak(); 531 template<typename P>
532 V8_INLINE P* ClearWeak();
533
534 // TODO(dcarney): remove this.
535 V8_INLINE void ClearWeak() { ClearWeak<void>(); }
531 536
532 /** 537 /**
533 * Marks the reference to this object independent. Garbage collector is free 538 * Marks the reference to this object independent. Garbage collector is free
534 * to ignore any object groups containing this object. Weak callback for an 539 * to ignore any object groups containing this object. Weak callback for an
535 * independent handle should not assume that it will be preceded by a global 540 * independent handle should not assume that it will be preceded by a global
536 * GC prologue callback or followed by a global GC epilogue callback. 541 * GC prologue callback or followed by a global GC epilogue callback.
537 */ 542 */
538 V8_INLINE void MarkIndependent(); 543 V8_INLINE void MarkIndependent();
539 544
540 /** 545 /**
(...skipping 28 matching lines...) Expand all
569 574
570 private: 575 private:
571 friend class Isolate; 576 friend class Isolate;
572 friend class Utils; 577 friend class Utils;
573 template<class F> friend class Handle; 578 template<class F> friend class Handle;
574 template<class F> friend class Local; 579 template<class F> friend class Local;
575 template<class F1, class F2> friend class Persistent; 580 template<class F1, class F2> friend class Persistent;
576 template<class F> friend class UniquePersistent; 581 template<class F> friend class UniquePersistent;
577 template<class F> friend class PersistentBase; 582 template<class F> friend class PersistentBase;
578 template<class F> friend class ReturnValue; 583 template<class F> friend class ReturnValue;
584 template<class F1, class F2, class F3> friend class PersistentValueMap;
579 585
580 explicit V8_INLINE PersistentBase(T* val) : val_(val) {} 586 explicit V8_INLINE PersistentBase(T* val) : val_(val) {}
581 PersistentBase(PersistentBase& other); // NOLINT 587 PersistentBase(PersistentBase& other); // NOLINT
582 void operator=(PersistentBase&); 588 void operator=(PersistentBase&);
583 V8_INLINE static T* New(Isolate* isolate, T* that); 589 V8_INLINE static T* New(Isolate* isolate, T* that);
584 590
585 T* val_; 591 T* val_;
586 }; 592 };
587 593
588 594
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 : PersistentBase<T>(rvalue.object->val_) { 780 : PersistentBase<T>(rvalue.object->val_) {
775 rvalue.object->val_ = 0; 781 rvalue.object->val_ = 0;
776 } 782 }
777 V8_INLINE ~UniquePersistent() { this->Reset(); } 783 V8_INLINE ~UniquePersistent() { this->Reset(); }
778 /** 784 /**
779 * Move via assignment. 785 * Move via assignment.
780 */ 786 */
781 template<class S> 787 template<class S>
782 V8_INLINE UniquePersistent& operator=(UniquePersistent<S> rhs) { 788 V8_INLINE UniquePersistent& operator=(UniquePersistent<S> rhs) {
783 TYPE_CHECK(T, S); 789 TYPE_CHECK(T, S);
790 this->Reset();
784 this->val_ = rhs.val_; 791 this->val_ = rhs.val_;
785 rhs.val_ = 0; 792 rhs.val_ = 0;
786 return *this; 793 return *this;
787 } 794 }
788 /** 795 /**
789 * Cast operator for moves. 796 * Cast operator for moves.
790 */ 797 */
791 V8_INLINE operator RValue() { return RValue(this); } 798 V8_INLINE operator RValue() { return RValue(this); }
792 /** 799 /**
793 * Pass allows returning uniques from functions, etc. 800 * Pass allows returning uniques from functions, etc.
794 */ 801 */
795 V8_INLINE UniquePersistent Pass() { return UniquePersistent(RValue(this)); } 802 V8_INLINE UniquePersistent Pass() { return UniquePersistent(RValue(this)); }
796 803
797 private: 804 private:
798 UniquePersistent(UniquePersistent&); 805 UniquePersistent(UniquePersistent&);
799 void operator=(UniquePersistent&); 806 void operator=(UniquePersistent&);
800 }; 807 };
801 808
802 809
810 typedef uintptr_t PersistentContainerValue;
811 static const uintptr_t kPersistentContainerNotFound = 0;
812
813 /**
814 * A map wrapper that allows using UniquePersistent as a mapped value.
815 * C++11 embedders don't need this class, as they can use UniquePersistent
816 * directly in std containers.
817 **/
818 template<class K, class V, class Traits>
819 class PersistentValueMap {
820 public:
821 V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {}
822
823 V8_INLINE ~PersistentValueMap() { Clear(); }
824
825 V8_INLINE Isolate* GetIsolate() { return isolate_; }
826
827 V8_INLINE size_t Size() { return Traits::Size(&impl_); }
828
829 V8_INLINE Local<V> Get(const K& key) {
830 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
831 }
832
833 UniquePersistent<V> Set(const K& key, Local<V> value) {
834 UniquePersistent<V> persistent(isolate_, value);
835 if (Traits::kIsWeak) {
836 persistent.template SetWeak<typename Traits::WeakCallbackDataType>(
837 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback);
838 }
839 PersistentContainerValue old_value =
840 Traits::Set(&impl_, key, ClearAndLeak(&persistent));
841 return Release(old_value).Pass();
842 }
843
844 V8_INLINE UniquePersistent<V> Remove(const K& key) {
845 return Release(Traits::Remove(&impl_, key)).Pass();
846 }
847
848 /**
849 * Traverses the map repeatedly,
850 * in case side effects of disposal cause insertions.
851 **/
852 void Clear();
853
854 private:
855 PersistentValueMap(PersistentValueMap&);
856 void operator=(PersistentValueMap&);
857
858 static void WeakCallback(
859 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data);
860 V8_INLINE static V* FromVal(PersistentContainerValue v) {
861 return reinterpret_cast<V*>(v);
862 }
863 V8_INLINE static PersistentContainerValue ClearAndLeak(
864 UniquePersistent<V>* persistent) {
865 V* v = persistent->val_;
866 persistent->val_ = 0;
867 return reinterpret_cast<PersistentContainerValue>(v);
868 }
869 V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) {
870 UniquePersistent<V> p;
871 p.val_ = FromVal(v);
872 if (Traits::kIsWeak && !p.IsEmpty()) {
873 Traits::DisposeCallbackData(
874 p.template ClearWeak<typename Traits::WeakCallbackDataType>());
875 }
876 return p.Pass();
877 }
878
879 Isolate* isolate_;
880 typename Traits::Impl impl_;
881 };
882
883
803 /** 884 /**
804 * A stack-allocated class that governs a number of local handles. 885 * A stack-allocated class that governs a number of local handles.
805 * After a handle scope has been created, all local handles will be 886 * After a handle scope has been created, all local handles will be
806 * allocated within that handle scope until either the handle scope is 887 * allocated within that handle scope until either the handle scope is
807 * deleted or another handle scope is created. If there is already a 888 * deleted or another handle scope is created. If there is already a
808 * handle scope and a new one is created, all allocations will take 889 * handle scope and a new one is created, all allocations will take
809 * place in the new handle scope until it is deleted. After that, 890 * place in the new handle scope until it is deleted. After that,
810 * new handles will again be allocated in the original handle scope. 891 * new handles will again be allocated in the original handle scope.
811 * 892 *
812 * After the handle scope of a local handle has been deleted the 893 * After the handle scope of a local handle has been deleted the
(...skipping 3966 matching lines...) Expand 10 before | Expand all | Expand 10 after
4779 V8(); 4860 V8();
4780 4861
4781 static internal::Object** GlobalizeReference(internal::Isolate* isolate, 4862 static internal::Object** GlobalizeReference(internal::Isolate* isolate,
4782 internal::Object** handle); 4863 internal::Object** handle);
4783 static internal::Object** CopyPersistent(internal::Object** handle); 4864 static internal::Object** CopyPersistent(internal::Object** handle);
4784 static void DisposeGlobal(internal::Object** global_handle); 4865 static void DisposeGlobal(internal::Object** global_handle);
4785 typedef WeakCallbackData<Value, void>::Callback WeakCallback; 4866 typedef WeakCallbackData<Value, void>::Callback WeakCallback;
4786 static void MakeWeak(internal::Object** global_handle, 4867 static void MakeWeak(internal::Object** global_handle,
4787 void* data, 4868 void* data,
4788 WeakCallback weak_callback); 4869 WeakCallback weak_callback);
4789 static void ClearWeak(internal::Object** global_handle); 4870 static void* ClearWeak(internal::Object** global_handle);
4790 static void Eternalize(Isolate* isolate, 4871 static void Eternalize(Isolate* isolate,
4791 Value* handle, 4872 Value* handle,
4792 int* index); 4873 int* index);
4793 static Local<Value> GetEternal(Isolate* isolate, int index); 4874 static Local<Value> GetEternal(Isolate* isolate, int index);
4794 4875
4795 template <class T> friend class Handle; 4876 template <class T> friend class Handle;
4796 template <class T> friend class Local; 4877 template <class T> friend class Local;
4797 template <class T> friend class Eternal; 4878 template <class T> friend class Eternal;
4798 template <class T> friend class PersistentBase; 4879 template <class T> friend class PersistentBase;
4799 template <class T, class M> friend class Persistent; 4880 template <class T, class M> friend class Persistent;
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after
5692 template <class T> 5773 template <class T>
5693 template <typename P> 5774 template <typename P>
5694 void PersistentBase<T>::SetWeak( 5775 void PersistentBase<T>::SetWeak(
5695 P* parameter, 5776 P* parameter,
5696 typename WeakCallbackData<T, P>::Callback callback) { 5777 typename WeakCallbackData<T, P>::Callback callback) {
5697 SetWeak<T, P>(parameter, callback); 5778 SetWeak<T, P>(parameter, callback);
5698 } 5779 }
5699 5780
5700 5781
5701 template <class T> 5782 template <class T>
5702 void PersistentBase<T>::ClearWeak() { 5783 template<typename P>
5703 V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)); 5784 P* PersistentBase<T>::ClearWeak() {
5785 return reinterpret_cast<P*>(
5786 V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)));
5704 } 5787 }
5705 5788
5706 5789
5707 template <class T> 5790 template <class T>
5708 void PersistentBase<T>::MarkIndependent() { 5791 void PersistentBase<T>::MarkIndependent() {
5709 typedef internal::Internals I; 5792 typedef internal::Internals I;
5710 if (this->IsEmpty()) return; 5793 if (this->IsEmpty()) return;
5711 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), 5794 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
5712 true, 5795 true,
5713 I::kNodeIsIndependentShift); 5796 I::kNodeIsIndependentShift);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5746 template <class T> 5829 template <class T>
5747 uint16_t PersistentBase<T>::WrapperClassId() const { 5830 uint16_t PersistentBase<T>::WrapperClassId() const {
5748 typedef internal::Internals I; 5831 typedef internal::Internals I;
5749 if (this->IsEmpty()) return 0; 5832 if (this->IsEmpty()) return 0;
5750 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); 5833 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_);
5751 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; 5834 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
5752 return *reinterpret_cast<uint16_t*>(addr); 5835 return *reinterpret_cast<uint16_t*>(addr);
5753 } 5836 }
5754 5837
5755 5838
5839 template<class K, class V, class Traits>
5840 void PersistentValueMap<K, V, Traits>::Clear() {
5841 typedef typename Traits::Iterator It;
5842 HandleScope handle_scope(isolate_);
5843 // TODO(dcarney): figure out if this swap and loop is necessary.
5844 while (!Traits::Empty(&impl_)) {
5845 typename Traits::Impl impl;
5846 Traits::Swap(impl_, impl);
5847 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
5848 Traits::DisposeCallback(&impl, Release(Traits::Value(i)).Pass());
5849 }
5850 }
5851 }
5852
5853
5854 template<class K, class V, class Traits>
5855 void PersistentValueMap<K, V, Traits>::WeakCallback(
5856 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
5857 typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data);
5858 K key = Traits::KeyFromWeakCallbackData(data);
5859 PersistentContainerValue value = Traits::Remove(impl, key);
5860 // TODO(dcarney): this should be an const in Traits instead of kIsWeak.
5861 if (data.GetValue().IsEmpty()) { // Zombied handle.
5862 // TODO(dcarney): zombie callback/push on zombie queue.
5863 } else {
5864 Traits::DisposeCallback(impl, Release(value).Pass());
5865 }
5866 Traits::DisposeCallbackData(data.GetParameter());
5867 }
5868
5869
5756 template<typename T> 5870 template<typename T>
5757 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} 5871 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {}
5758 5872
5759 template<typename T> 5873 template<typename T>
5760 template<typename S> 5874 template<typename S>
5761 void ReturnValue<T>::Set(const Persistent<S>& handle) { 5875 void ReturnValue<T>::Set(const Persistent<S>& handle) {
5762 TYPE_CHECK(T, S); 5876 TYPE_CHECK(T, S);
5763 if (V8_UNLIKELY(handle.IsEmpty())) { 5877 if (V8_UNLIKELY(handle.IsEmpty())) {
5764 *value_ = GetDefaultValue(); 5878 *value_ = GetDefaultValue();
5765 } else { 5879 } else {
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
6455 */ 6569 */
6456 6570
6457 6571
6458 } // namespace v8 6572 } // namespace v8
6459 6573
6460 6574
6461 #undef TYPE_CHECK 6575 #undef TYPE_CHECK
6462 6576
6463 6577
6464 #endif // V8_H_ 6578 #endif // V8_H_
OLDNEW
« no previous file with comments | « no previous file | src/api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698