Compute accurate token count when loading from snapshot

With --compiler-stats, traverse heap at isolate shutdown to
find all token streams and compute the number of tokens in
the stream. This fixes incorrect token counts when loading
from snapshot.

R=asiva@google.com

Review URL: https://codereview.chromium.org//1131493007

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45806 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
hausner@google.com 2015-05-15 00:11:01 +00:00
parent 0bf3812043
commit feae1f7b82
5 changed files with 52 additions and 17 deletions

View file

@ -5,6 +5,7 @@
#include "vm/compiler_stats.h"
#include "vm/flags.h"
#include "vm/object_graph.h"
#include "vm/timer.h"
@ -13,6 +14,43 @@ namespace dart {
DEFINE_FLAG(bool, compiler_stats, false, "Compiler stat counters.");
class TokenStreamVisitor : public ObjectGraph::Visitor {
public:
explicit TokenStreamVisitor(CompilerStats* compiler_stats)
: obj_(Object::Handle()), stats_(compiler_stats) {
}
virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
RawObject* raw_obj = it->Get();
if (raw_obj->IsFreeListElement()) {
return kProceed;
}
obj_ = raw_obj;
if (obj_.GetClassId() == TokenStream::kClassId) {
TokenStream::Iterator tkit(TokenStream::Cast(obj_),
0,
TokenStream::Iterator::kNoNewlines);
Token::Kind kind = tkit.CurrentTokenKind();
while (kind != Token::kEOS) {
++stats_->num_tokens_total;
if (kind == Token::kIDENT) {
++stats_->num_ident_tokens_total;
} else if (Token::NeedsLiteralToken(kind)) {
++stats_->num_literal_tokens_total;
}
tkit.Advance();
kind = tkit.CurrentTokenKind();
}
}
return kProceed;
}
private:
Object& obj_;
CompilerStats* stats_;
};
CompilerStats::CompilerStats(Isolate* isolate)
: isolate_(isolate),
parser_timer(true, "parser timer"),
@ -34,7 +72,6 @@ CompilerStats::CompilerStats(Isolate* isolate)
num_ident_tokens_total(0),
num_tokens_consumed(0),
num_token_checks(0),
num_tokens_rewind(0),
num_tokens_lookahead(0),
num_classes_compiled(0),
num_functions_compiled(0),
@ -51,6 +88,16 @@ void CompilerStats::Print() {
if (!FLAG_compiler_stats) {
return;
}
// Traverse the heap and compute number of tokens in all
// TokenStream objects.
num_tokens_total = 0;
num_literal_tokens_total = 0;
num_ident_tokens_total = 0;
TokenStreamVisitor visitor(this);
ObjectGraph graph(isolate_);
graph.IterateObjects(&visitor);
OS::Print("==== Compiler Stats for isolate '%s' ====\n",
isolate_->debugger_name());
OS::Print("Number of tokens: %" Pd64 "\n", num_tokens_total);
@ -61,8 +108,6 @@ void CompilerStats::Print() {
(1.0 * num_tokens_consumed) / num_tokens_total);
OS::Print("Tokens checked: %" Pd64 " (%.2f times tokens consumed)\n",
num_token_checks, (1.0 * num_token_checks) / num_tokens_consumed);
OS::Print("Token rewind: %" Pd64 " (%" Pd64 "%% of tokens checked)\n",
num_tokens_rewind, (100 * num_tokens_rewind) / num_token_checks);
OS::Print("Token lookahead: %" Pd64 " (%" Pd64 "%% of tokens checked)\n",
num_tokens_lookahead,
(100 * num_tokens_lookahead) / num_token_checks);

View file

@ -49,7 +49,6 @@ class CompilerStats {
int64_t num_ident_tokens_total;
int64_t num_tokens_consumed;
int64_t num_token_checks;
int64_t num_tokens_rewind;
int64_t num_tokens_lookahead;
int64_t num_classes_compiled;

View file

@ -1418,6 +1418,10 @@ void Isolate::Shutdown() {
StackZone stack_zone(this);
HandleScope handle_scope(this);
if (compiler_stats_ != NULL) {
compiler_stats()->Print();
}
// Notify exit listeners that this isolate is shutting down.
if (object_store() != NULL) {
NotifyExitListeners();
@ -1444,9 +1448,6 @@ void Isolate::Shutdown() {
api_state()->weak_persistent_handles().VisitHandles(&visitor);
api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor);
if (compiler_stats_ != NULL) {
compiler_stats()->Print();
}
if (FLAG_trace_isolates) {
heap()->PrintSizes();
megamorphic_cache_table()->PrintSizes();

View file

@ -7964,21 +7964,14 @@ RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens,
for (intptr_t i = 0; i < len; i++) {
Scanner::TokenDescriptor token = tokens[i];
if (token.kind == Token::kIDENT) { // Identifier token.
if (FLAG_compiler_stats) {
INC_STAT(isolate, num_ident_tokens_total, 1);
}
data.AddIdentToken(token.literal);
} else if (Token::NeedsLiteralToken(token.kind)) { // Literal token.
if (FLAG_compiler_stats) {
INC_STAT(isolate, num_literal_tokens_total, 1);
}
data.AddLiteralToken(token);
} else { // Keyword, pseudo keyword etc.
ASSERT(token.kind < Token::kNumTokens);
data.AddSimpleToken(token.kind);
}
}
INC_STAT(isolate, num_tokens_total, len);
data.AddSimpleToken(Token::kEOS); // End of stream.
// Create and setup the token stream object.

View file

@ -443,9 +443,6 @@ void Parser::set_current_class(const Class& value) {
void Parser::SetPosition(intptr_t position) {
if (position < TokenPos() && position != 0) {
INC_STAT(I, num_tokens_rewind, (TokenPos() - position));
}
tokens_iterator_.SetCurrentPosition(position);
token_kind_ = Token::kILLEGAL;
}