Reviewers: Vyacheslav Egorov,
Message:
PTAL.
Description:
Release stack trace data after firing Error.stack accessor.
BUG=v8:2308
Please review this at http://codereview.chromium.org/10886012/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/messages.js
M test/cctest/test-heap.cc
Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index
4da38051f9200746250867e23f9cc4228c524178..a947bbfbe05aab380e6a78ca5b264d07f380ce63
100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -766,18 +766,18 @@ function DefineOneShotAccessor(obj, name, fun) {
// Note that the accessors consistently operate on 'obj', not 'this'.
// Since the object may occur in someone else's prototype chain we
// can't rely on 'this' being the same as 'obj'.
- var hasBeenSet = false;
var value;
+ var getter_function = fun;
var getter = function() {
- if (hasBeenSet) {
+ if (getter_function == null) {
return value;
}
- hasBeenSet = true;
- value = fun(obj);
+ value = getter_function(obj);
+ getter_function = null;
return value;
};
var setter = function(v) {
- hasBeenSet = true;
+ getter_function = null;
value = v;
};
%DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM);
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index
ec2fb3dd6e0e4ef85a4ceb2e9d0b7b7ab251a389..cf435bfd296590ec33ddabc3b30d23d30ef190e9
100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -2183,3 +2183,57 @@ TEST(IncrementalMarkingClearsPolymorhpicIC) {
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
CHECK(ic_after->ic_state() == UNINITIALIZED);
}
+
+
+class SourceResource: public v8::String::ExternalAsciiStringResource {
+ public:
+ explicit SourceResource(const char* data, int* counter)
+ : data_(data), length_(strlen(data)), counter_(counter) { }
+
+ virtual void Dispose() {
+ i::DeleteArray(data_);
+ if (counter_ != NULL) ++*counter_;
+ }
+
+ const char* data() const { return data_; }
+
+ size_t length() const { return length_; }
+
+ private:
+ const char* data_;
+ size_t length_;
+ int* counter_;
+};
+
+
+
+TEST(ReleaseStackTraceData) {
+ // Test that the data retained by the Error.stack accessor is released
+ // after the first time the accessor is fired. We use external string
+ // to check whether the data is being released since the external string
+ // resource's callback is fired when the external string is GC'ed.
+ InitializeVM();
+ v8::HandleScope scope;
+ static const char* source = "var error = 1; "
+ "try { "
+ " throw new Error(); "
+ "} catch (e) { "
+ " error = e; "
+ "} ";
+ int counter = 0;
+ SourceResource* resource = new SourceResource(i::StrDup(source),
&counter);
+ {
+ v8::HandleScope scope;
+ v8::Handle<v8::String> source_string =
v8::String::NewExternal(resource);
+ v8::Script::Compile(source_string)->Run();
+ CHECK(counter == 0);
+ }
+ HEAP->CollectAllAvailableGarbage();
+ CHECK(counter == 0); // External source is being retained by the stack
trace.
+
+ CompileRun("error.stack;");
+ HEAP->CollectAllAvailableGarbage();
+ CHECK(counter == 1); // External source has been released.
+
+ delete resource;
+}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev