Release stack trace data after firing Error.stack accessor.
BUG=v8:2308 Review URL: https://chromiumcodereview.appspot.com/10886012 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12403 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
de3c3c0198
commit
5419ee7ba0
@ -762,22 +762,21 @@ function GetStackTraceLine(recv, fun, pos, isGlobal) {
|
||||
|
||||
// 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);
|
||||
|
@ -2183,3 +2183,58 @@ 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)
|
||||
: 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user