Chromium Code Reviews

Side by Side Diff: include/v8.h

Issue 189463019: Implement PersistentValueMap, a map that stores UniquePersistent values. (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.
Jump to:
View unified diff | | 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 122 matching lines...)
133 class Data; 133 class Data;
134 template<typename T> class PropertyCallbackInfo; 134 template<typename T> class PropertyCallbackInfo;
135 class StackTrace; 135 class StackTrace;
136 class StackFrame; 136 class StackFrame;
137 class Isolate; 137 class Isolate;
138 class DeclaredAccessorDescriptor; 138 class DeclaredAccessorDescriptor;
139 class ObjectOperationDescriptor; 139 class ObjectOperationDescriptor;
140 class RawOperationDescriptor; 140 class RawOperationDescriptor;
141 class CallHandlerHelper; 141 class CallHandlerHelper;
142 class EscapableHandleScope; 142 class EscapableHandleScope;
143 template <typename T>
144 class ReturnValue;
143 145
144 namespace internal { 146 namespace internal {
145 class Arguments; 147 class Arguments;
146 class Heap; 148 class Heap;
147 class HeapObject; 149 class HeapObject;
148 class Isolate; 150 class Isolate;
149 class Object; 151 class Object;
150 template<typename T> class CustomArguments; 152 template<typename T> class CustomArguments;
151 class PropertyCallbackArguments; 153 class PropertyCallbackArguments;
152 class FunctionCallbackArguments; 154 class FunctionCallbackArguments;
(...skipping 252 matching lines...)
405 template<class F> friend class Handle; 407 template<class F> friend class Handle;
406 template<class F> friend class Local; 408 template<class F> friend class Local;
407 template<class F> friend class FunctionCallbackInfo; 409 template<class F> friend class FunctionCallbackInfo;
408 template<class F> friend class PropertyCallbackInfo; 410 template<class F> friend class PropertyCallbackInfo;
409 friend class String; 411 friend class String;
410 friend class Object; 412 friend class Object;
411 friend class Context; 413 friend class Context;
412 template<class F> friend class internal::CustomArguments; 414 template<class F> friend class internal::CustomArguments;
413 friend class HandleScope; 415 friend class HandleScope;
414 friend class EscapableHandleScope; 416 friend class EscapableHandleScope;
417 template <class F1, class F2, class F3>
418 friend class PersistentValueMap;
415 419
416 V8_INLINE static Local<T> New(Isolate* isolate, T* that); 420 V8_INLINE static Local<T> New(Isolate* isolate, T* that);
417 }; 421 };
418 422
419 423
420 // Eternal handles are set-once handles that live for the life of the isolate. 424 // Eternal handles are set-once handles that live for the life of the isolate.
421 template <class T> class Eternal { 425 template <class T> class Eternal {
422 public: 426 public:
423 V8_INLINE Eternal() : index_(kInitialValue) { } 427 V8_INLINE Eternal() : index_(kInitialValue) { }
424 template<class S> 428 template<class S>
(...skipping 95 matching lines...)
520 template<typename P> 524 template<typename P>
521 V8_INLINE void SetWeak( 525 V8_INLINE void SetWeak(
522 P* parameter, 526 P* parameter,
523 typename WeakCallbackData<T, P>::Callback callback); 527 typename WeakCallbackData<T, P>::Callback callback);
524 528
525 template<typename S, typename P> 529 template<typename S, typename P>
526 V8_INLINE void SetWeak( 530 V8_INLINE void SetWeak(
527 P* parameter, 531 P* parameter,
528 typename WeakCallbackData<S, P>::Callback callback); 532 typename WeakCallbackData<S, P>::Callback callback);
529 533
530 V8_INLINE void ClearWeak(); 534 template <typename P>
535 V8_INLINE P* ClearWeak();
536
537 // TODO(dcarney): remove this.
538 V8_INLINE void ClearWeak() { ClearWeak<void>(); }
531 539
532 /** 540 /**
533 * Marks the reference to this object independent. Garbage collector is free 541 * Marks the reference to this object independent. Garbage collector is free
534 * to ignore any object groups containing this object. Weak callback for an 542 * 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 543 * 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. 544 * GC prologue callback or followed by a global GC epilogue callback.
537 */ 545 */
538 V8_INLINE void MarkIndependent(); 546 V8_INLINE void MarkIndependent();
539 547
540 /** 548 /**
(...skipping 28 matching lines...)
569 577
570 private: 578 private:
571 friend class Isolate; 579 friend class Isolate;
572 friend class Utils; 580 friend class Utils;
573 template<class F> friend class Handle; 581 template<class F> friend class Handle;
574 template<class F> friend class Local; 582 template<class F> friend class Local;
575 template<class F1, class F2> friend class Persistent; 583 template<class F1, class F2> friend class Persistent;
576 template<class F> friend class UniquePersistent; 584 template<class F> friend class UniquePersistent;
577 template<class F> friend class PersistentBase; 585 template<class F> friend class PersistentBase;
578 template<class F> friend class ReturnValue; 586 template<class F> friend class ReturnValue;
587 template <class F1, class F2, class F3>
588 friend class PersistentValueMap;
579 589
580 explicit V8_INLINE PersistentBase(T* val) : val_(val) {} 590 explicit V8_INLINE PersistentBase(T* val) : val_(val) {}
581 PersistentBase(PersistentBase& other); // NOLINT 591 PersistentBase(PersistentBase& other); // NOLINT
582 void operator=(PersistentBase&); 592 void operator=(PersistentBase&);
583 V8_INLINE static T* New(Isolate* isolate, T* that); 593 V8_INLINE static T* New(Isolate* isolate, T* that);
584 594
585 T* val_; 595 T* val_;
586 }; 596 };
587 597
588 598
(...skipping 185 matching lines...)
774 : PersistentBase<T>(rvalue.object->val_) { 784 : PersistentBase<T>(rvalue.object->val_) {
775 rvalue.object->val_ = 0; 785 rvalue.object->val_ = 0;
776 } 786 }
777 V8_INLINE ~UniquePersistent() { this->Reset(); } 787 V8_INLINE ~UniquePersistent() { this->Reset(); }
778 /** 788 /**
779 * Move via assignment. 789 * Move via assignment.
780 */ 790 */
781 template<class S> 791 template<class S>
782 V8_INLINE UniquePersistent& operator=(UniquePersistent<S> rhs) { 792 V8_INLINE UniquePersistent& operator=(UniquePersistent<S> rhs) {
783 TYPE_CHECK(T, S); 793 TYPE_CHECK(T, S);
794 this->Reset();
784 this->val_ = rhs.val_; 795 this->val_ = rhs.val_;
785 rhs.val_ = 0; 796 rhs.val_ = 0;
786 return *this; 797 return *this;
787 } 798 }
788 /** 799 /**
789 * Cast operator for moves. 800 * Cast operator for moves.
790 */ 801 */
791 V8_INLINE operator RValue() { return RValue(this); } 802 V8_INLINE operator RValue() { return RValue(this); }
792 /** 803 /**
793 * Pass allows returning uniques from functions, etc. 804 * Pass allows returning uniques from functions, etc.
794 */ 805 */
795 V8_INLINE UniquePersistent Pass() { return UniquePersistent(RValue(this)); } 806 V8_INLINE UniquePersistent Pass() { return UniquePersistent(RValue(this)); }
796 807
797 private: 808 private:
798 UniquePersistent(UniquePersistent&); 809 UniquePersistent(UniquePersistent&);
799 void operator=(UniquePersistent&); 810 void operator=(UniquePersistent&);
800 }; 811 };
801 812
813 typedef uintptr_t PersistentContainerValue;
814 static const uintptr_t kPersistentContainerNotFound = 0;
815
816 /**
817 * A map wrapper that allows using UniquePersistent as a mapped value.
818 * C++11 embedders don't need this class, as they can use UniquePersistent
819 * directly in std containers.
820 **/
821 template <class K, class V, class Traits>
822 class PersistentValueMap {
823 public:
824 V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {}
825
826 V8_INLINE ~PersistentValueMap() { Clear(); }
827
828 V8_INLINE Isolate* GetIsolate() { return isolate_; }
829
830 V8_INLINE size_t Size() { return Traits::Size(&impl_); }
831
832 V8_INLINE Local<V> Get(const K& key) {
833 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
834 }
835
836 V8_INLINE bool Contains(const K& key) {
837 return Traits::Get(&impl_, key) != 0;
838 }
839
840 V8_INLINE bool SetReturnValueFrom(const K& key,
dcarney 2014/03/10 11:35:23 just SetReturnValue
vogelheim 2014/03/10 19:00:46 Done.
vogelheim 2014/03/10 19:00:46 Done.
841 ReturnValue<Value>& returnValue);
842
843 V8_INLINE void SetReference(const K& key,
844 const v8::Persistent<v8::Object>& parent) {
845 Persistent<V> persistent;
846 persistent.val_ = FromVal(Traits::Get(&impl_, key));
847 GetIsolate()->SetReference(parent, persistent);
dcarney 2014/03/10 11:35:23 create a private function to take a raw pointer
vogelheim 2014/03/10 19:00:46 Done. That is, I'm reusing a private SetReference
848 persistent.val_ = 0;
849 }
850
851 UniquePersistent<V> Set(const K& key, Local<V> value) {
dcarney 2014/03/10 11:35:23 this can't work, since the Set should 0 the unique
vogelheim 2014/03/10 19:00:46 Not done. (As discussed offline, the SetUnique re
852 UniquePersistent<V> persistent(isolate_, value);
853 return SetUnique(key, &persistent);
854 }
855
856 UniquePersistent<V> SetWithConfig(const K& key, Local<V> value,
dcarney 2014/03/10 11:35:23 same here, plus this is not a very generic api
vogelheim 2014/03/10 19:00:46 Kinda done. I've changed this to take a UniquePers
857 uint16_t classId, bool independent) {
858 UniquePersistent<V> persistent(isolate_, value);
859 persistent.SetWrapperClassId(classId);
860 if (independent) persistent.MarkIndependent();
861 return SetUnique(key, &persistent);
862 }
863
864 V8_INLINE UniquePersistent<V> Remove(const K& key) {
865 return Release(Traits::Remove(&impl_, key)).Pass();
866 }
867
868 /**
869 * Traverses the map repeatedly,
870 * in case side effects of disposal cause insertions.
871 **/
872 void Clear();
873
874 private:
875 PersistentValueMap(PersistentValueMap&);
876 void operator=(PersistentValueMap&);
877
878 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
879 if (Traits::kIsWeak) {
880 Local<V> value(Local<V>::New(isolate_, *persistent));
881 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
882 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback);
883 }
884 PersistentContainerValue old_value =
885 Traits::Set(&impl_, key, ClearAndLeak(persistent));
886 return Release(old_value).Pass();
887 }
888
889 static void WeakCallback(
890 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data);
891 V8_INLINE static V* FromVal(PersistentContainerValue v) {
892 return reinterpret_cast<V*>(v);
893 }
894 V8_INLINE static PersistentContainerValue ClearAndLeak(
895 UniquePersistent<V>* persistent) {
896 V* v = persistent->val_;
897 persistent->val_ = 0;
898 return reinterpret_cast<PersistentContainerValue>(v);
899 }
900 V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) {
901 UniquePersistent<V> p;
902 p.val_ = FromVal(v);
903 if (Traits::kIsWeak && !p.IsEmpty()) {
904 Traits::DisposeCallbackData(
905 p.template ClearWeak<typename Traits::WeakCallbackDataType>());
906 }
907 return p.Pass();
908 }
909
910 Isolate* isolate_;
911 typename Traits::Impl impl_;
912 };
802 913
803 /** 914 /**
804 * A stack-allocated class that governs a number of local handles. 915 * A stack-allocated class that governs a number of local handles.
805 * After a handle scope has been created, all local handles will be 916 * After a handle scope has been created, all local handles will be
806 * allocated within that handle scope until either the handle scope is 917 * allocated within that handle scope until either the handle scope is
807 * deleted or another handle scope is created. If there is already a 918 * 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 919 * 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, 920 * place in the new handle scope until it is deleted. After that,
810 * new handles will again be allocated in the original handle scope. 921 * new handles will again be allocated in the original handle scope.
811 * 922 *
(...skipping 3948 matching lines...)
4760 V8(); 4871 V8();
4761 4872
4762 static internal::Object** GlobalizeReference(internal::Isolate* isolate, 4873 static internal::Object** GlobalizeReference(internal::Isolate* isolate,
4763 internal::Object** handle); 4874 internal::Object** handle);
4764 static internal::Object** CopyPersistent(internal::Object** handle); 4875 static internal::Object** CopyPersistent(internal::Object** handle);
4765 static void DisposeGlobal(internal::Object** global_handle); 4876 static void DisposeGlobal(internal::Object** global_handle);
4766 typedef WeakCallbackData<Value, void>::Callback WeakCallback; 4877 typedef WeakCallbackData<Value, void>::Callback WeakCallback;
4767 static void MakeWeak(internal::Object** global_handle, 4878 static void MakeWeak(internal::Object** global_handle,
4768 void* data, 4879 void* data,
4769 WeakCallback weak_callback); 4880 WeakCallback weak_callback);
4770 static void ClearWeak(internal::Object** global_handle); 4881 static void* ClearWeak(internal::Object** global_handle);
4771 static void Eternalize(Isolate* isolate, 4882 static void Eternalize(Isolate* isolate,
4772 Value* handle, 4883 Value* handle,
4773 int* index); 4884 int* index);
4774 static Local<Value> GetEternal(Isolate* isolate, int index); 4885 static Local<Value> GetEternal(Isolate* isolate, int index);
4775 4886
4776 template <class T> friend class Handle; 4887 template <class T> friend class Handle;
4777 template <class T> friend class Local; 4888 template <class T> friend class Local;
4778 template <class T> friend class Eternal; 4889 template <class T> friend class Eternal;
4779 template <class T> friend class PersistentBase; 4890 template <class T> friend class PersistentBase;
4780 template <class T, class M> friend class Persistent; 4891 template <class T, class M> friend class Persistent;
(...skipping 890 matching lines...)
5671 5782
5672 5783
5673 template <class T> 5784 template <class T>
5674 template <typename P> 5785 template <typename P>
5675 void PersistentBase<T>::SetWeak( 5786 void PersistentBase<T>::SetWeak(
5676 P* parameter, 5787 P* parameter,
5677 typename WeakCallbackData<T, P>::Callback callback) { 5788 typename WeakCallbackData<T, P>::Callback callback) {
5678 SetWeak<T, P>(parameter, callback); 5789 SetWeak<T, P>(parameter, callback);
5679 } 5790 }
5680 5791
5681
5682 template <class T> 5792 template <class T>
5683 void PersistentBase<T>::ClearWeak() { 5793 template <typename P>
5684 V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)); 5794 P* PersistentBase<T>::ClearWeak() {
5795 return reinterpret_cast<P*>(
5796 V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)));
5685 } 5797 }
5686 5798
5687 5799
5688 template <class T> 5800 template <class T>
5689 void PersistentBase<T>::MarkIndependent() { 5801 void PersistentBase<T>::MarkIndependent() {
5690 typedef internal::Internals I; 5802 typedef internal::Internals I;
5691 if (this->IsEmpty()) return; 5803 if (this->IsEmpty()) return;
5692 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), 5804 I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
5693 true, 5805 true,
5694 I::kNodeIsIndependentShift); 5806 I::kNodeIsIndependentShift);
(...skipping 31 matching lines...)
5726 5838
5727 template <class T> 5839 template <class T>
5728 uint16_t PersistentBase<T>::WrapperClassId() const { 5840 uint16_t PersistentBase<T>::WrapperClassId() const {
5729 typedef internal::Internals I; 5841 typedef internal::Internals I;
5730 if (this->IsEmpty()) return 0; 5842 if (this->IsEmpty()) return 0;
5731 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); 5843 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_);
5732 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; 5844 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
5733 return *reinterpret_cast<uint16_t*>(addr); 5845 return *reinterpret_cast<uint16_t*>(addr);
5734 } 5846 }
5735 5847
5848 template <class K, class V, class Traits>
5849 bool PersistentValueMap<K, V, Traits>::SetReturnValueFrom(
5850 const K& key, ReturnValue<Value>& returnValue) {
5851 PersistentContainerValue value = Traits::Get(&impl_, key);
5852 if (value != 0) {
5853 // TODO(vogelheim) Do I need to create that Handle? I didn't see a
5854 // ReturnValue::Set without one.
5855 returnValue.Set(Local<V>::New(isolate_, FromVal(value)));
dcarney 2014/03/10 11:35:23 no new handle, just install it directly in return
vogelheim 2014/03/10 19:00:46 Done.
5856 return true;
5857 } else {
5858 return false;
5859 }
5860 }
5861
5862 template <class K, class V, class Traits>
5863 void PersistentValueMap<K, V, Traits>::Clear() {
5864 typedef typename Traits::Iterator It;
5865 HandleScope handle_scope(isolate_);
5866 // TODO(dcarney): figure out if this swap and loop is necessary.
5867 while (!Traits::Empty(&impl_)) {
5868 typename Traits::Impl impl;
5869 Traits::Swap(impl_, impl);
5870 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
5871 Traits::DisposeByKey(&impl, Traits::Key(i));
5872 Traits::DisposeByValue(Release(Traits::Value(i)).Pass(), isolate_);
5873 }
5874 }
5875 }
5876
5877 template <class K, class V, class Traits>
5878 void PersistentValueMap<K, V, Traits>::WeakCallback(
5879 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
5880 typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data);
5881 K key = Traits::KeyFromWeakCallbackData(data);
5882 PersistentContainerValue value = Traits::Remove(impl, key);
5883 // TODO(dcarney): this should be an const in Traits instead of kIsWeak.
5884 if (data.GetValue().IsEmpty()) { // Zombied handle.
dcarney 2014/03/10 11:35:23 remove this clause
vogelheim 2014/03/10 19:00:46 Done.
5885 // TODO(dcarney): zombie callback/push on zombie queue.
5886 } else {
5887 Traits::DisposeByKey(impl, key);
5888 Traits::DisposeByValue(Release(value).Pass(), data.GetIsolate());
5889 }
5890 Traits::DisposeCallbackData(data.GetParameter());
5891 }
5736 5892
5737 template<typename T> 5893 template<typename T>
5738 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} 5894 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {}
5739 5895
5740 template<typename T> 5896 template<typename T>
5741 template<typename S> 5897 template<typename S>
5742 void ReturnValue<T>::Set(const Persistent<S>& handle) { 5898 void ReturnValue<T>::Set(const Persistent<S>& handle) {
5743 TYPE_CHECK(T, S); 5899 TYPE_CHECK(T, S);
5744 if (V8_UNLIKELY(handle.IsEmpty())) { 5900 if (V8_UNLIKELY(handle.IsEmpty())) {
5745 *value_ = GetDefaultValue(); 5901 *value_ = GetDefaultValue();
(...skipping 690 matching lines...)
6436 */ 6592 */
6437 6593
6438 6594
6439 } // namespace v8 6595 } // namespace v8
6440 6596
6441 6597
6442 #undef TYPE_CHECK 6598 #undef TYPE_CHECK
6443 6599
6444 6600
6445 #endif // V8_H_ 6601 #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