Introduce ZoneScope class to keep track of zone deletion. Remove

unsafe calls to Zone::DeleteAll() from parser and use ZoneScopes
instead.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@54 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mads.s.ager@gmail.com 2008-09-01 06:06:52 +00:00
parent 5540a1a43c
commit 36a4d039b1
4 changed files with 41 additions and 26 deletions

View File

@ -48,28 +48,6 @@ DEFINE_bool(print_scopes, false, "print scopes");
#endif #endif
// Helper class to keep track of compilation nesting and to do proper
// cleanups of generated ASTs.
class CompilationTracker BASE_EMBEDDED {
public:
CompilationTracker() {
++nesting_;
}
~CompilationTracker() {
// If we're leaving the top-level compilation, we must make sure
// to get rid of all generated ASTs.
if (--nesting_ == 0) Zone::DeleteAll();
}
private:
static int nesting_;
};
int CompilationTracker::nesting_ = 0;
static Handle<Code> MakeCode(FunctionLiteral* literal, static Handle<Code> MakeCode(FunctionLiteral* literal,
Handle<Script> script, Handle<Script> script,
bool is_eval) { bool is_eval) {
@ -108,7 +86,7 @@ static Handle<JSFunction> MakeFunction(bool is_global,
Handle<Script> script, Handle<Script> script,
v8::Extension* extension, v8::Extension* extension,
ScriptDataImpl* pre_data) { ScriptDataImpl* pre_data) {
CompilationTracker tracker; ZoneScope zone_scope(DELETE_ON_EXIT);
// Make sure we have an initial stack limit. // Make sure we have an initial stack limit.
StackGuard guard; StackGuard guard;
@ -232,7 +210,7 @@ Handle<JSFunction> Compiler::CompileEval(bool is_global,
bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared) { bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared) {
CompilationTracker tracker; ZoneScope zone_scope(DELETE_ON_EXIT);
// The VM is in the COMPILER state until exiting this function. // The VM is in the COMPILER state until exiting this function.
VMState state(COMPILER); VMState state(COMPILER);

View File

@ -731,6 +731,8 @@ bool Parser::PreParseProgram(unibrow::CharacterStream* stream) {
FunctionLiteral* Parser::ParseProgram(Handle<String> source, FunctionLiteral* Parser::ParseProgram(Handle<String> source,
unibrow::CharacterStream* stream, unibrow::CharacterStream* stream,
bool in_global_context) { bool in_global_context) {
ZoneScope zone_scope(DONT_DELETE_ON_EXIT);
StatsRateScope timer(&Counters::parse); StatsRateScope timer(&Counters::parse);
Counters::total_parse_size.Increment(source->length()); Counters::total_parse_size.Increment(source->length());
@ -773,7 +775,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
// If there was a syntax error we have to get rid of the AST // If there was a syntax error we have to get rid of the AST
// and it is not safe to do so before the scope has been deleted. // and it is not safe to do so before the scope has been deleted.
if (result == NULL) Zone::DeleteAll(); if (result == NULL) zone_scope.DeleteOnExit();
return result; return result;
} }
@ -782,6 +784,7 @@ FunctionLiteral* Parser::ParseLazy(Handle<String> source,
Handle<String> name, Handle<String> name,
int start_position, int start_position,
bool is_expression) { bool is_expression) {
ZoneScope zone_scope(DONT_DELETE_ON_EXIT);
StatsRateScope timer(&Counters::parse_lazy); StatsRateScope timer(&Counters::parse_lazy);
Counters::total_parse_size.Increment(source->length()); Counters::total_parse_size.Increment(source->length());
SafeStringInputBuffer buffer(source.location()); SafeStringInputBuffer buffer(source.location());
@ -819,7 +822,7 @@ FunctionLiteral* Parser::ParseLazy(Handle<String> source,
// not safe to do before scope has been deleted. // not safe to do before scope has been deleted.
if (result == NULL) { if (result == NULL) {
Top::StackOverflow(); Top::StackOverflow();
Zone::DeleteAll(); zone_scope.DeleteOnExit();
} }
return result; return result;
} }

View File

@ -37,6 +37,7 @@ Address Zone::limit_ = 0;
bool AssertNoZoneAllocation::allow_allocation_ = true; bool AssertNoZoneAllocation::allow_allocation_ = true;
int ZoneScope::nesting_ = 0;
// Segments represent chunks of memory: They have starting address // Segments represent chunks of memory: They have starting address
// (encoded in the this pointer) and a size in bytes. Segments are // (encoded in the this pointer) and a size in bytes. Segments are

View File

@ -31,6 +31,14 @@
namespace v8 { namespace internal { namespace v8 { namespace internal {
// Zone scopes are in one of two modes. Either they delete the zone
// on exit or they do not.
enum ZoneScopeMode {
DELETE_ON_EXIT,
DONT_DELETE_ON_EXIT
};
// The Zone supports very fast allocation of small chunks of // The Zone supports very fast allocation of small chunks of
// memory. The chunks cannot be deallocated individually, but instead // memory. The chunks cannot be deallocated individually, but instead
// the Zone supports deallocating all chunks in one fast // the Zone supports deallocating all chunks in one fast
@ -143,6 +151,31 @@ class ZoneList: public List<T, ZoneListAllocationPolicy> {
}; };
// ZoneScopes keep track of the current parsing and compilation
// nesting and cleans up generated ASTs in the Zone when exiting the
// outer-most scope.
class ZoneScope BASE_EMBEDDED {
public:
explicit ZoneScope(ZoneScopeMode mode) : mode_(mode) {
nesting_++;
}
~ZoneScope() {
if (--nesting_ == 0 && mode_ == DELETE_ON_EXIT) Zone::DeleteAll();
}
// For ZoneScopes that do not delete on exit by default, call this
// method to request deletion on exit.
void DeleteOnExit() {
mode_ = DELETE_ON_EXIT;
}
private:
ZoneScopeMode mode_;
static int nesting_;
};
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_ZONE_H_ #endif // V8_ZONE_H_