Commit ebb75c23 authored by yurys@chromium.org's avatar yurys@chromium.org

Provide a way for iterating through all external strings referenced from the JS heap

Review URL: http://codereview.chromium.org/9139018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10400 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b3e0761e
...@@ -2848,6 +2848,17 @@ class V8EXPORT StartupDataDecompressor { // NOLINT ...@@ -2848,6 +2848,17 @@ class V8EXPORT StartupDataDecompressor { // NOLINT
*/ */
typedef bool (*EntropySource)(unsigned char* buffer, size_t length); typedef bool (*EntropySource)(unsigned char* buffer, size_t length);
/**
* Interface for iterating though all external resources in the heap.
*/
class V8EXPORT ExternalResourceVisitor { // NOLINT
public:
virtual ~ExternalResourceVisitor() {}
virtual void VisitExternalString(Handle<String> string) {}
};
/** /**
* Container class for static utility functions. * Container class for static utility functions.
*/ */
...@@ -3203,6 +3214,13 @@ class V8EXPORT V8 { ...@@ -3203,6 +3214,13 @@ class V8EXPORT V8 {
*/ */
static void GetHeapStatistics(HeapStatistics* heap_statistics); static void GetHeapStatistics(HeapStatistics* heap_statistics);
/**
* Iterates through all external resources referenced from current isolate
* heap. This method is not expected to be used except for debugging purposes
* and may be quite slow.
*/
static void VisitExternalResources(ExternalResourceVisitor* visitor);
/** /**
* Optional notification that the embedder is idle. * Optional notification that the embedder is idle.
* V8 uses the notification to reduce memory footprint. * V8 uses the notification to reduce memory footprint.
......
...@@ -4049,6 +4049,13 @@ void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) { ...@@ -4049,6 +4049,13 @@ void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
} }
void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::V8::VisitExternalResources");
isolate->heap()->VisitExternalResources(visitor);
}
bool v8::V8::IdleNotification(int hint) { bool v8::V8::IdleNotification(int hint) {
// Returning true tells the caller that it need not // Returning true tells the caller that it need not
// continue to call IdleNotification. // continue to call IdleNotification.
......
...@@ -1354,6 +1354,28 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { ...@@ -1354,6 +1354,28 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
} }
void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
AssertNoAllocation no_allocation;
class VisitorAdapter : public ObjectVisitor {
public:
explicit VisitorAdapter(v8::ExternalResourceVisitor* visitor)
: visitor_(visitor) {}
virtual void VisitPointers(Object** start, Object** end) {
for (Object** p = start; p < end; p++) {
if ((*p)->IsExternalString()) {
visitor_->VisitExternalString(Utils::ToLocal(
Handle<String>(String::cast(*p))));
}
}
}
private:
v8::ExternalResourceVisitor* visitor_;
} visitor_adapter(visitor);
external_string_table_.Iterate(&visitor_adapter);
}
class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> { class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> {
public: public:
static inline void VisitPointer(Heap* heap, Object** p) { static inline void VisitPointer(Heap* heap, Object** p) {
......
...@@ -1412,6 +1412,8 @@ class Heap { ...@@ -1412,6 +1412,8 @@ class Heap {
void ProcessWeakReferences(WeakObjectRetainer* retainer); void ProcessWeakReferences(WeakObjectRetainer* retainer);
void VisitExternalResources(v8::ExternalResourceVisitor* visitor);
// Helper function that governs the promotion policy from new space to // Helper function that governs the promotion policy from new space to
// old. If the object's old address lies below the new space's age // old. If the object's old address lies below the new space's age
// mark or if we've already filled the bottom 1/16th of the to space, // mark or if we've already filled the bottom 1/16th of the to space,
......
...@@ -13675,6 +13675,59 @@ THREADED_TEST(GetHeapStatistics) { ...@@ -13675,6 +13675,59 @@ THREADED_TEST(GetHeapStatistics) {
} }
class VisitorImpl : public v8::ExternalResourceVisitor {
public:
VisitorImpl(TestResource* r1, TestResource* r2)
: resource1_(r1),
resource2_(r2),
found_resource1_(false),
found_resource2_(false) {}
virtual ~VisitorImpl() {}
virtual void VisitExternalString(v8::Handle<v8::String> string) {
if (!string->IsExternal()) {
CHECK(string->IsExternalAscii());
return;
}
v8::String::ExternalStringResource* resource =
string->GetExternalStringResource();
CHECK(resource);
if (resource1_ == resource) {
CHECK(!found_resource1_);
found_resource1_ = true;
}
if (resource2_ == resource) {
CHECK(!found_resource2_);
found_resource2_ = true;
}
}
void CheckVisitedResources() {
CHECK(found_resource1_);
CHECK(found_resource2_);
}
private:
v8::String::ExternalStringResource* resource1_;
v8::String::ExternalStringResource* resource2_;
bool found_resource1_;
bool found_resource2_;
};
TEST(VisitExternalStrings) {
v8::HandleScope scope;
LocalContext env;
const char* string = "Some string";
uint16_t* two_byte_string = AsciiToTwoByteString(string);
TestResource* resource1 = new TestResource(two_byte_string);
v8::Local<v8::String> string1 = v8::String::NewExternal(resource1);
TestResource* resource2 = new TestResource(two_byte_string);
v8::Local<v8::String> string2 = v8::String::NewExternal(resource2);
VisitorImpl visitor(resource1, resource2);
v8::V8::VisitExternalResources(&visitor);
visitor.CheckVisitedResources();
}
static double DoubleFromBits(uint64_t value) { static double DoubleFromBits(uint64_t value) {
double target; double target;
memcpy(&target, &value, sizeof(target)); memcpy(&target, &value, sizeof(target));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment