Index: src/api.h |
=================================================================== |
--- src/api.h (revision 7267) |
+++ src/api.h (working copy) |
@@ -122,7 +122,7 @@ |
template <typename T> |
static inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) { |
STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); |
- return v8::internal::Factory::NewProxy( |
+ return FACTORY->NewProxy( |
reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj))); |
} |
@@ -157,7 +157,6 @@ |
RegisteredExtension* next_auto_; |
ExtensionTraversalState state_; |
static RegisteredExtension* first_extension_; |
- static RegisteredExtension* first_auto_extension_; |
}; |
@@ -321,16 +320,83 @@ |
namespace internal { |
+// Tracks string usage to help make better decisions when |
+// externalizing strings. |
+// |
+// Implementation note: internally this class only tracks fresh |
+// strings and keeps a single use counter for them. |
+class StringTracker { |
+ public: |
+ // Records that the given string's characters were copied to some |
+ // external buffer. If this happens often we should honor |
+ // externalization requests for the string. |
+ void RecordWrite(Handle<String> string) { |
+ Address address = reinterpret_cast<Address>(*string); |
+ Address top = isolate_->heap()->NewSpaceTop(); |
+ if (IsFreshString(address, top)) { |
+ IncrementUseCount(top); |
+ } |
+ } |
+ |
+ // Estimates freshness and use frequency of the given string based |
+ // on how close it is to the new space top and the recorded usage |
+ // history. |
+ inline bool IsFreshUnusedString(Handle<String> string) { |
+ Address address = reinterpret_cast<Address>(*string); |
+ Address top = isolate_->heap()->NewSpaceTop(); |
+ return IsFreshString(address, top) && IsUseCountLow(top); |
+ } |
+ |
+ private: |
+ StringTracker() : use_count_(0), last_top_(NULL), isolate_(NULL) { } |
+ |
+ static inline bool IsFreshString(Address string, Address top) { |
+ return top - kFreshnessLimit <= string && string <= top; |
+ } |
+ |
+ inline bool IsUseCountLow(Address top) { |
+ if (last_top_ != top) return true; |
+ return use_count_ < kUseLimit; |
+ } |
+ |
+ inline void IncrementUseCount(Address top) { |
+ if (last_top_ != top) { |
+ use_count_ = 0; |
+ last_top_ = top; |
+ } |
+ ++use_count_; |
+ } |
+ |
+ // Single use counter shared by all fresh strings. |
+ int use_count_; |
+ |
+ // Last new space top when the use count above was valid. |
+ Address last_top_; |
+ |
+ Isolate* isolate_; |
+ |
+ // How close to the new space top a fresh string has to be. |
+ static const int kFreshnessLimit = 1024; |
+ |
+ // The number of uses required to consider a string useful. |
+ static const int kUseLimit = 32; |
+ |
+ friend class Isolate; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(StringTracker); |
+}; |
+ |
+ |
// This class is here in order to be able to declare it a friend of |
// HandleScope. Moving these methods to be members of HandleScope would be |
-// neat in some ways, but it would expose external implementation details in |
+// neat in some ways, but it would expose internal implementation details in |
// our public header file, which is undesirable. |
// |
-// There is a singleton instance of this class to hold the per-thread data. |
-// For multithreaded V8 programs this data is copied in and out of storage |
+// An isolate has a single instance of this class to hold the current thread's |
+// data. In multithreaded V8 programs this data is copied in and out of storage |
// so that the currently executing thread always has its own copy of this |
// data. |
-class HandleScopeImplementer { |
+ISOLATED_CLASS HandleScopeImplementer { |
public: |
HandleScopeImplementer() |
@@ -341,16 +407,14 @@ |
ignore_out_of_memory_(false), |
call_depth_(0) { } |
- static HandleScopeImplementer* instance(); |
- |
// Threading support for handle data. |
static int ArchiveSpacePerThread(); |
- static char* RestoreThread(char* from); |
- static char* ArchiveThread(char* to); |
- static void FreeThreadResources(); |
+ char* RestoreThread(char* from); |
+ char* ArchiveThread(char* to); |
+ void FreeThreadResources(); |
// Garbage collection support. |
- static void Iterate(v8::internal::ObjectVisitor* v); |
+ void Iterate(v8::internal::ObjectVisitor* v); |
static char* Iterate(v8::internal::ObjectVisitor* v, char* data); |