Revision: 12403
Author: [email protected]
Date: Wed Aug 29 00:51:48 2012
Log: Release stack trace data after firing Error.stack accessor.
BUG=v8:2308
Review URL: https://chromiumcodereview.appspot.com/10886012
http://code.google.com/p/v8/source/detail?r=12403
Modified:
/branches/bleeding_edge/src/messages.js
/branches/bleeding_edge/test/cctest/test-heap.cc
=======================================
--- /branches/bleeding_edge/src/messages.js Wed Jul 11 04:35:19 2012
+++ /branches/bleeding_edge/src/messages.js Wed Aug 29 00:51:48 2012
@@ -762,22 +762,21 @@
// Defines accessors for a property that is calculated the first time
// the property is read.
-function DefineOneShotAccessor(obj, name, fun) {
+function DefineOneShotAccessor(obj, name, value_factory) {
// 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() {
- if (hasBeenSet) {
+ if (value_factory == null) {
return value;
}
- hasBeenSet = true;
- value = fun(obj);
+ value = value_factory(obj);
+ value_factory = null;
return value;
};
var setter = function(v) {
- hasBeenSet = true;
+ value_factory = null;
value = v;
};
%DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM);
=======================================
--- /branches/bleeding_edge/test/cctest/test-heap.cc Mon Aug 27 09:08:27
2012
+++ /branches/bleeding_edge/test/cctest/test-heap.cc Wed Aug 29 00:51:48
2012
@@ -2183,3 +2183,58 @@
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)
+ : data_(data), length_(strlen(data)) { }
+
+ virtual void Dispose() {
+ i::DeleteArray(data_);
+ data_ = NULL;
+ }
+
+ const char* data() const { return data_; }
+
+ size_t length() const { return length_; }
+
+ bool IsDisposed() { return data_ == NULL; }
+
+ private:
+ const char* data_;
+ size_t length_;
+};
+
+
+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; "
+ "} ";
+ SourceResource* resource = new SourceResource(i::StrDup(source));
+ {
+ v8::HandleScope scope;
+ v8::Handle<v8::String> source_string =
v8::String::NewExternal(resource);
+ v8::Script::Compile(source_string)->Run();
+ CHECK(!resource->IsDisposed());
+ }
+ HEAP->CollectAllAvailableGarbage();
+ // External source is being retained by the stack trace.
+ CHECK(!resource->IsDisposed());
+
+ CompileRun("error.stack; error.stack;");
+ HEAP->CollectAllAvailableGarbage();
+ // External source has been released.
+ CHECK(resource->IsDisposed());
+
+ delete resource;
+}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev