Revision: 20511
Author:   [email protected]
Date:     Fri Apr  4 12:36:23 2014 UTC
Log:      Update tests to use the new compilation API + related fixes.

Esp. get rid of PreCompile in tests, as it's going to be removed.

Notes:
- The new compilation API doesn't have a separate precompilation phase, so there
is no separate way to check for errors except checking the compilation
errors. Removed some tests which don't make sense any more.
- test-api/Regress31661 didn't make sense as a regression test even before the compilation API changes, because Blink doesn't precompile this short scripts. So detecting this kind of errors (see crbug.com/31661 for more information) cannot rely
on precompilation errors.
- test-parsing/PreParserStrictOctal has nothing to do with PreParser, and the comment
about "forcing preparsing" was just wrong.
- test-api/PreCompile was supposed to test that "pre-compilation (aka
preparsing) can be called without initializing the whole VM"; that's no longer
true, since there's no separate precompilation step in the new compile
API. There are other tests (test-parsing/DontRegressPreParserDataSizes) which
ensure that we produce cached data.
- Updated tests which test preparsing to use PreParser directly (not via the
 preparsing API).
- In the new compilation API, the user doesn't need to deal with ScriptData
ever. It's only used internally, and needed in tests that test internal aspects
(e.g., modify the cached data before passing it back).
- Some tests which used to test preparse + parse now test first time parse +
  second time parse, and had to be modified to ensure we don't hit the
  compilation cache.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/225743002
http://code.google.com/p/v8/source/detail?r=20511

Modified:
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/test/cctest/cctest.h
 /branches/bleeding_edge/test/cctest/test-api.cc
 /branches/bleeding_edge/test/cctest/test-parsing.cc
 /branches/bleeding_edge/tools/parser-shell.cc

=======================================
--- /branches/bleeding_edge/src/parser.h        Wed Apr  2 12:38:01 2014 UTC
+++ /branches/bleeding_edge/src/parser.h        Fri Apr  4 12:36:23 2014 UTC
@@ -114,6 +114,13 @@
         ? store_[PreparseDataConstants::kSymbolCountOffset]
         : 0;
   }
+  int function_count() {
+    int functions_size =
+ static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
+    if (functions_size < 0) return 0;
+    if (functions_size % FunctionEntry::kSize != 0) return 0;
+    return functions_size / FunctionEntry::kSize;
+  }
   // The following functions should only be called if SanityCheck has
   // returned true.
bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
=======================================
--- /branches/bleeding_edge/test/cctest/cctest.h Wed Mar 19 13:24:13 2014 UTC +++ /branches/bleeding_edge/test/cctest/cctest.h Fri Apr 4 12:36:23 2014 UTC
@@ -346,19 +346,13 @@


static inline v8::Local<v8::Value> PreCompileCompileRun(const char* source) { + // Compile once just to get the preparse data, then compile the second time
+  // using the data.
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
-  v8::Local<v8::String> source_string =
-      v8::String::NewFromUtf8(isolate, source);
-  v8::ScriptData* preparse = v8::ScriptData::PreCompile(source_string);
-  v8::ScriptCompiler::Source script_source(
-      source_string, new v8::ScriptCompiler::CachedData(
- reinterpret_cast<const uint8_t*>(preparse->Data()),
-                         preparse->Length()));
-  v8::Local<v8::Script> script =
-      v8::ScriptCompiler::Compile(isolate, &script_source);
-  v8::Local<v8::Value> result = script->Run();
-  delete preparse;
-  return result;
+  v8::ScriptCompiler::Source script_source(v8_str(source));
+  v8::ScriptCompiler::Compile(isolate, &script_source,
+                              v8::ScriptCompiler::kProduceDataToCache);
+  return v8::ScriptCompiler::Compile(isolate, &script_source)->Run();
 }


=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Thu Apr 3 12:41:37 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Fri Apr 4 12:36:23 2014 UTC
@@ -14821,76 +14821,34 @@
   CHECK(g1->Call(global, 0, NULL).IsEmpty());
   CHECK(g2->Call(global, 0, NULL).IsEmpty());
 }
-
-
-// This test verifies that pre-compilation (aka preparsing) can be called
-// without initializing the whole VM. Thus we cannot run this test in a
-// multi-threaded setup.
-TEST(PreCompile) {
- // TODO(155): This test would break without the initialization of V8. This is
-  // a workaround for now to make this test not fail.
-  v8::V8::Initialize();
-  v8::Isolate* isolate = CcTest::isolate();
-  HandleScope handle_scope(isolate);
-  const char* script = "function foo(a) { return a+1; }";
-  v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8(
-      isolate, script, v8::String::kNormalString, i::StrLength(script)));
-  CHECK_NE(sd->Length(), 0);
-  CHECK_NE(sd->Data(), NULL);
-  CHECK(!sd->HasError());
-  delete sd;
-}
-
-
-TEST(PreCompileWithError) {
-  v8::V8::Initialize();
-  v8::Isolate* isolate = CcTest::isolate();
-  HandleScope handle_scope(isolate);
-  const char* script = "function foo(a) { return 1 * * 2; }";
-  v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8(
-      isolate, script, v8::String::kNormalString, i::StrLength(script)));
-  CHECK(sd->HasError());
-  delete sd;
-}
-
-
-TEST(Regress31661) {
-  v8::V8::Initialize();
-  v8::Isolate* isolate = CcTest::isolate();
-  HandleScope handle_scope(isolate);
-  const char* script = " The Definintive Guide";
-  v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8(
-      isolate, script, v8::String::kNormalString, i::StrLength(script)));
-  CHECK(sd->HasError());
-  delete sd;
-}


 // Tests that ScriptData can be serialized and deserialized.
 TEST(PreCompileSerialization) {
   v8::V8::Initialize();
-  v8::Isolate* isolate = CcTest::isolate();
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
   HandleScope handle_scope(isolate);
+
+  i::FLAG_min_preparse_length = 0;
   const char* script = "function foo(a) { return a+1; }";
-  v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8(
-      isolate, script, v8::String::kNormalString, i::StrLength(script)));
-
+  v8::ScriptCompiler::Source source(v8_str(script));
+  v8::ScriptCompiler::Compile(isolate, &source,
+                              v8::ScriptCompiler::kProduceDataToCache);
   // Serialize.
-  int serialized_data_length = sd->Length();
-  char* serialized_data = i::NewArray<char>(serialized_data_length);
-  i::OS::MemCopy(serialized_data, sd->Data(), serialized_data_length);
+  const v8::ScriptCompiler::CachedData* cd = source.GetCachedData();
+  char* serialized_data = i::NewArray<char>(cd->length);
+  i::OS::MemCopy(serialized_data, cd->data, cd->length);

   // Deserialize.
-  v8::ScriptData* deserialized_sd =
-      v8::ScriptData::New(serialized_data, serialized_data_length);
+  v8::ScriptData* deserialized =
+      v8::ScriptData::New(serialized_data, cd->length);

   // Verify that the original is the same as the deserialized.
-  CHECK_EQ(sd->Length(), deserialized_sd->Length());
-  CHECK_EQ(0, memcmp(sd->Data(), deserialized_sd->Data(), sd->Length()));
-  CHECK_EQ(sd->HasError(), deserialized_sd->HasError());
+  CHECK_EQ(cd->length, deserialized->Length());
+  CHECK_EQ(0, memcmp(cd->data, deserialized->Data(), cd->length));

-  delete sd;
-  delete deserialized_sd;
+  delete deserialized;
   i::DeleteArray(serialized_data);
 }

@@ -14908,17 +14866,25 @@
 }


-// Attempts to deserialize bad data.
-TEST(PreCompileInvalidPreparseDataError) {
+TEST(CompileWithInvalidCachedData) {
   v8::V8::Initialize();
   v8::Isolate* isolate = CcTest::isolate();
   LocalContext context;
   v8::HandleScope scope(context->GetIsolate());
+  i::FLAG_min_preparse_length = 0;

   const char* script = "function foo(){ return 5;}\n"
       "function bar(){ return 6 + 7;}  foo();";
-  v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8(
-      isolate, script, v8::String::kNormalString, i::StrLength(script)));
+  v8::ScriptCompiler::Source source(v8_str(script));
+  v8::ScriptCompiler::Compile(isolate, &source,
+                              v8::ScriptCompiler::kProduceDataToCache);
+  // source owns its cached data. Create a ScriptData based on it. The user
+ // never needs to create ScriptDatas any more; we only need it here because we
+  // want to modify the data before passing it back.
+  const v8::ScriptCompiler::CachedData* cd = source.GetCachedData();
+  // ScriptData does not take ownership of the buffers passed to it.
+  v8::ScriptData* sd =
+ v8::ScriptData::New(reinterpret_cast<const char*>(cd->data), cd->length);
   CHECK(!sd->HasError());
   // ScriptDataImpl private implementation details
   const int kHeaderSize = i::PreparseDataConstants::kHeaderSize;
@@ -14932,12 +14898,18 @@
sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryEndOffset] = 0;
   v8::TryCatch try_catch;

-  v8::ScriptCompiler::Source script_source(
-      String::NewFromUtf8(isolate, script),
+ // Make the script slightly different so that we don't hit the compilation
+  // cache. Don't change the lenghts of tokens.
+  const char* script2 = "function foo(){ return 6;}\n"
+      "function bar(){ return 6 + 7;}  foo();";
+  v8::ScriptCompiler::Source source2(
+      v8_str(script2),
+      // CachedData doesn't take ownership of the buffers, Source takes
+      // ownership of CachedData.
       new v8::ScriptCompiler::CachedData(
           reinterpret_cast<const uint8_t*>(sd->Data()), sd->Length()));
   Local<v8::UnboundScript> compiled_script =
-      v8::ScriptCompiler::CompileUnbound(isolate, &script_source);
+      v8::ScriptCompiler::CompileUnbound(isolate, &source2);

   CHECK(try_catch.HasCaught());
   String::Utf8Value exception_value(try_catch.Message()->Get());
@@ -14950,19 +14922,20 @@
   // Overwrite function bar's start position with 200.  The function entry
   // will not be found when searching for it by position and we should fall
   // back on eager compilation.
-  sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8(
-      isolate, script, v8::String::kNormalString, i::StrLength(script)));
+  // ScriptData does not take ownership of the buffers passed to it.
+ sd = v8::ScriptData::New(reinterpret_cast<const char*>(cd->data), cd->length);
   sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data()));
sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] =
       200;
-  v8::ScriptCompiler::Source script_source2(
-      String::NewFromUtf8(isolate, script),
+  const char* script3 = "function foo(){ return 7;}\n"
+      "function bar(){ return 6 + 7;}  foo();";
+  v8::ScriptCompiler::Source source3(
+      v8_str(script3),
       new v8::ScriptCompiler::CachedData(
           reinterpret_cast<const uint8_t*>(sd->Data()), sd->Length()));
   compiled_script =
-      v8::ScriptCompiler::CompileUnbound(isolate, &script_source2);
+      v8::ScriptCompiler::CompileUnbound(isolate, &source3);
   CHECK(!try_catch.HasCaught());
-
   delete sd;
 }

=======================================
--- /branches/bleeding_edge/test/cctest/test-parsing.cc Thu Apr 3 12:41:37 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-parsing.cc Fri Apr 4 12:36:23 2014 UTC
@@ -144,24 +144,36 @@
   int marker;
   CcTest::i_isolate()->stack_guard()->SetStackLimit(
       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
-
+ uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
   for (int i = 0; tests[i]; i++) {
-    v8::Handle<v8::String> source = v8::String::NewFromUtf8(
- isolate, tests[i], v8::String::kNormalString, i::StrLength(tests[i]));
-    v8::ScriptData* data = v8::ScriptData::PreCompile(source);
-    CHECK(data != NULL && !data->HasError());
-    delete data;
+    const i::byte* source =
+        reinterpret_cast<const i::byte*>(tests[i]);
+    i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(tests[i]));
+    i::CompleteParserRecorder log;
+    i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
+    scanner.Initialize(&stream);
+    i::PreParser preparser(&scanner, &log, stack_limit);
+    preparser.set_allow_lazy(true);
+    i::PreParser::PreParseResult result = preparser.PreParseProgram();
+    CHECK_EQ(i::PreParser::kPreParseSuccess, result);
+    i::ScriptDataImpl data(log.ExtractData());
+    CHECK(!data.has_error());
   }

   for (int i = 0; fail_tests[i]; i++) {
-    v8::Handle<v8::String> source =
-        v8::String::NewFromUtf8(isolate,
-                                fail_tests[i],
-                                v8::String::kNormalString,
-                                i::StrLength(fail_tests[i]));
-    v8::ScriptData* data = v8::ScriptData::PreCompile(source);
-    CHECK(data == NULL || data->HasError());
-    delete data;
+    const i::byte* source =
+        reinterpret_cast<const i::byte*>(fail_tests[i]);
+ i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(fail_tests[i]));
+    i::CompleteParserRecorder log;
+    i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
+    scanner.Initialize(&stream);
+    i::PreParser preparser(&scanner, &log, stack_limit);
+    preparser.set_allow_lazy(true);
+    i::PreParser::PreParseResult result = preparser.PreParseProgram();
+    // Even in the case of a syntax error, kPreParseSuccess is returned.
+    CHECK_EQ(i::PreParser::kPreParseSuccess, result);
+    i::ScriptDataImpl data(log.ExtractData());
+    CHECK(data.has_error());
   }
 }

@@ -180,7 +192,7 @@
 };


-TEST(Preparsing) {
+TEST(UsingCachedData) {
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope handles(isolate);
   v8::Local<v8::Context> context = v8::Context::New(isolate);
@@ -203,60 +215,22 @@
       "var y = { get getter() { return 42; }, "
       "          set setter(v) { this.value = v; }};";
   int source_length = i::StrLength(source);
-  const char* error_source = "var x = y z;";
-  int error_source_length = i::StrLength(error_source);

- v8::ScriptData* preparse = v8::ScriptData::PreCompile(v8::String::NewFromUtf8(
-      isolate, source, v8::String::kNormalString, source_length));
-  CHECK(!preparse->HasError());
-  bool lazy_flag = i::FLAG_lazy;
-  {
-    i::FLAG_lazy = true;
-    ScriptResource* resource = new ScriptResource(source, source_length);
-    v8::ScriptCompiler::Source script_source(
-        v8::String::NewExternal(isolate, resource),
-        new v8::ScriptCompiler::CachedData(
-            reinterpret_cast<const uint8_t*>(preparse->Data()),
-            preparse->Length()));
-    v8::ScriptCompiler::Compile(isolate,
-                                &script_source);
-  }
-
-  {
-    i::FLAG_lazy = false;
+  // ScriptResource will be deleted when the corresponding String is GCd.
+  v8::ScriptCompiler::Source script_source(v8::String::NewExternal(
+      isolate, new ScriptResource(source, source_length)));
+  i::FLAG_min_preparse_length = 0;
+  v8::ScriptCompiler::Compile(isolate, &script_source,
+                              v8::ScriptCompiler::kProduceDataToCache);
+  CHECK(script_source.GetCachedData());

-    ScriptResource* resource = new ScriptResource(source, source_length);
-    v8::ScriptCompiler::Source script_source(
-        v8::String::NewExternal(isolate, resource),
-        new v8::ScriptCompiler::CachedData(
-            reinterpret_cast<const uint8_t*>(preparse->Data()),
-            preparse->Length()));
-    v8::ScriptCompiler::CompileUnbound(isolate, &script_source);
-  }
-  delete preparse;
+  // Compile the script again, using the cached data.
+  bool lazy_flag = i::FLAG_lazy;
+  i::FLAG_lazy = true;
+  v8::ScriptCompiler::Compile(isolate, &script_source);
+  i::FLAG_lazy = false;
+  v8::ScriptCompiler::CompileUnbound(isolate, &script_source);
   i::FLAG_lazy = lazy_flag;
-
-  // Syntax error.
-  v8::ScriptData* error_preparse = v8::ScriptData::PreCompile(
-      v8::String::NewFromUtf8(isolate,
-                              error_source,
-                              v8::String::kNormalString,
-                              error_source_length));
-  CHECK(error_preparse->HasError());
-  i::ScriptDataImpl *pre_impl =
-      reinterpret_cast<i::ScriptDataImpl*>(error_preparse);
-  i::Scanner::Location error_location =
-      pre_impl->MessageLocation();
-  // Error is at "z" in source, location 10..11.
-  CHECK_EQ(10, error_location.beg_pos);
-  CHECK_EQ(11, error_location.end_pos);
-  // Should not crash.
-  const char* message = pre_impl->BuildMessage();
-  i::Vector<const char*> args = pre_impl->BuildArgs();
-  CHECK_GT(strlen(message), 0);
-  args.Dispose();
-  i::DeleteArray(message);
-  delete error_preparse;
 }


@@ -472,15 +446,6 @@
       log->symbol_id_ = number + 1;
     }
   }
-  static int symbol_position(CompleteParserRecorder* log) {
-    return log->symbol_store_.size();
-  }
-  static int symbol_ids(CompleteParserRecorder* log) {
-    return log->symbol_id_;
-  }
-  static int function_position(CompleteParserRecorder* log) {
-    return log->function_store_.size();
-  }
 };

 }
@@ -536,9 +501,17 @@
   i::Utf8ToUtf16CharacterStream stream(
       reinterpret_cast<const i::byte*>(program),
       static_cast<unsigned>(strlen(program)));
-  i::ScriptDataImpl* data = i::PreParserApi::PreParse(isolate, &stream);
-  CHECK(data->HasError());
-  delete data;
+  i::CompleteParserRecorder log;
+  i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
+  scanner.Initialize(&stream);
+  i::PreParser preparser(&scanner, &log,
+ CcTest::i_isolate()->stack_guard()->real_climit());
+  preparser.set_allow_lazy(true);
+  i::PreParser::PreParseResult result = preparser.PreParseProgram();
+  // Even in the case of a syntax error, kPreParseSuccess is returned.
+  CHECK_EQ(i::PreParser::kPreParseSuccess, result);
+  i::ScriptDataImpl data(log.ExtractData());
+  CHECK(data.has_error());
 }


@@ -563,16 +536,23 @@
   i::Handle<i::String> source(
       factory->NewStringFromAscii(i::CStrVector(program)));
   i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
-  i::ScriptDataImpl* data = i::PreParserApi::PreParse(isolate, &stream);
-  CHECK(!data->HasError());
-
-  data->Initialize();
+  i::CompleteParserRecorder log;
+  i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
+  scanner.Initialize(&stream);
+  i::PreParser preparser(&scanner, &log,
+ CcTest::i_isolate()->stack_guard()->real_climit());
+  preparser.set_allow_lazy(true);
+  i::PreParser::PreParseResult result = preparser.PreParseProgram();
+  CHECK_EQ(i::PreParser::kPreParseSuccess, result);
+  i::ScriptDataImpl data(log.ExtractData());
+  CHECK(!data.has_error());
+  data.Initialize();

   int first_function =
       static_cast<int>(strstr(program, "function") - program);
   int first_lbrace = first_function + i::StrLength("function () ");
   CHECK_EQ('{', program[first_lbrace]);
-  i::FunctionEntry entry1 = data->GetFunctionEntry(first_lbrace);
+  i::FunctionEntry entry1 = data.GetFunctionEntry(first_lbrace);
   CHECK(!entry1.is_valid());

   int second_function =
@@ -580,10 +560,9 @@
   int second_lbrace =
       second_function + i::StrLength("function () ");
   CHECK_EQ('{', program[second_lbrace]);
-  i::FunctionEntry entry2 = data->GetFunctionEntry(second_lbrace);
+  i::FunctionEntry entry2 = data.GetFunctionEntry(second_lbrace);
   CHECK(entry2.is_valid());
   CHECK_EQ('}', program[entry2.end_pos() - 1]);
-  delete data;
 }


@@ -1556,10 +1535,9 @@
 }


-TEST(PreparserStrictOctal) {
+TEST(StrictOctal) {
// Test that syntax error caused by octal literal is reported correctly as
   // such (issue 2220).
-  v8::internal::FLAG_min_preparse_length = 1;  // Force preparsing.
   v8::V8::Initialize();
   v8::HandleScope scope(CcTest::isolate());
   v8::Context::Scope context_scope(
@@ -2086,9 +2064,12 @@


 TEST(DontRegressPreParserDataSizes) {
- // These tests make sure that PreParser doesn't start producing less data.
-
+ // These tests make sure that Parser doesn't start producing less "preparse
+  // data" (data which the embedder can cache).
   v8::V8::Initialize();
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope handles(isolate);
+
   int marker;
   CcTest::i_isolate()->stack_guard()->SetStackLimit(
       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
@@ -2118,45 +2099,37 @@
      1},
     {NULL, 0, 0}
   };
-  // Each function adds 5 elements to the preparse function data.
-  const int kDataPerFunction = 5;

-  typedef i::CompleteParserRecorderFriend F;
- uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
   for (int i = 0; test_cases[i].program; i++) {
     const char* program = test_cases[i].program;
-    i::Utf8ToUtf16CharacterStream stream(
-        reinterpret_cast<const i::byte*>(program),
-        static_cast<unsigned>(strlen(program)));
-    i::CompleteParserRecorder log;
-    i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
-    scanner.Initialize(&stream);
+    i::Factory* factory = CcTest::i_isolate()->factory();
+    i::Handle<i::String> source(
+        factory->NewStringFromUtf8(i::CStrVector(program)));
+    i::Handle<i::Script> script = factory->NewScript(source);
+    i::CompilationInfoWithZone info(script);
+    i::ScriptDataImpl* data = NULL;
+    info.SetCachedData(&data, i::PRODUCE_CACHED_DATA);
+    i::Parser::Parse(&info, true);
+    CHECK(data);
+    CHECK(!data->HasError());

-    i::PreParser preparser(&scanner, &log, stack_limit);
-    preparser.set_allow_lazy(true);
-    preparser.set_allow_natives_syntax(true);
-    i::PreParser::PreParseResult result = preparser.PreParseProgram();
-    CHECK_EQ(i::PreParser::kPreParseSuccess, result);
-    if (F::symbol_ids(&log) != test_cases[i].symbols) {
+    if (data->symbol_count() != test_cases[i].symbols) {
       i::OS::Print(
           "Expected preparse data for program:\n"
           "\t%s\n"
           "to contain %d symbols, however, received %d symbols.\n",
-          program, test_cases[i].symbols, F::symbol_ids(&log));
+          program, test_cases[i].symbols, data->symbol_count());
       CHECK(false);
     }
-    if (F::function_position(&log) !=
-          test_cases[i].functions * kDataPerFunction) {
+    if (data->function_count() != test_cases[i].functions) {
       i::OS::Print(
           "Expected preparse data for program:\n"
           "\t%s\n"
           "to contain %d functions, however, received %d functions.\n",
           program, test_cases[i].functions,
-          F::function_position(&log) / kDataPerFunction);
+          data->function_count());
       CHECK(false);
     }
-    i::ScriptDataImpl data(log.ExtractData());
-    CHECK(!data.has_error());
   }
 }

=======================================
--- /branches/bleeding_edge/tools/parser-shell.cc Mon Mar 24 14:43:41 2014 UTC +++ /branches/bleeding_edge/tools/parser-shell.cc Fri Apr 4 12:36:23 2014 UTC
@@ -44,15 +44,9 @@

 using namespace v8::internal;

-enum TestMode {
-  PreParseAndParse,
-  PreParse,
-  Parse
-};
-
 std::pair<TimeDelta, TimeDelta> RunBaselineParser(
     const char* fname, Encoding encoding, int repeat, v8::Isolate* isolate,
-    v8::Handle<v8::Context> context, TestMode test_mode) {
+    v8::Handle<v8::Context> context) {
   int length = 0;
   const byte* source = ReadFileAndRepeat(fname, &length, repeat);
   v8::Handle<v8::String> source_handle;
@@ -73,42 +67,41 @@
       break;
     }
   }
-  v8::ScriptData* cached_data = NULL;
-  TimeDelta preparse_time, parse_time;
-  if (test_mode == PreParseAndParse || test_mode == PreParse) {
+  TimeDelta parse_time1, parse_time2;
+  Handle<Script> script = Isolate::Current()->factory()->NewScript(
+      v8::Utils::OpenHandle(*source_handle));
+  i::ScriptDataImpl* cached_data_impl = NULL;
+  // First round of parsing (produce data to cache).
+  {
+    CompilationInfoWithZone info(script);
+    info.MarkAsGlobal();
+    info.SetCachedData(&cached_data_impl, i::PRODUCE_CACHED_DATA);
     ElapsedTimer timer;
     timer.Start();
-    cached_data = v8::ScriptData::PreCompile(source_handle);
-    preparse_time = timer.Elapsed();
-    if (cached_data == NULL || cached_data->HasError()) {
-      fprintf(stderr, "Preparsing failed\n");
+    // Allow lazy parsing; otherwise we won't produce cached data.
+    bool success = Parser::Parse(&info, true);
+    parse_time1 = timer.Elapsed();
+    if (!success) {
+      fprintf(stderr, "Parsing failed\n");
       return std::make_pair(TimeDelta(), TimeDelta());
     }
   }
-  if (test_mode == PreParseAndParse || test_mode == Parse) {
-    Handle<String> str = v8::Utils::OpenHandle(*source_handle);
-    i::Isolate* internal_isolate = str->GetIsolate();
-    Handle<Script> script = internal_isolate->factory()->NewScript(str);
+  // Second round of parsing (consume cached data).
+  {
     CompilationInfoWithZone info(script);
     info.MarkAsGlobal();
-    i::ScriptDataImpl* cached_data_impl =
-        static_cast<i::ScriptDataImpl*>(cached_data);
-    if (test_mode == PreParseAndParse) {
-      info.SetCachedData(&cached_data_impl,
-                         i::CONSUME_CACHED_DATA);
-    }
-    info.SetContext(v8::Utils::OpenHandle(*context));
+    info.SetCachedData(&cached_data_impl, i::CONSUME_CACHED_DATA);
     ElapsedTimer timer;
     timer.Start();
-    // Allow lazy parsing; otherwise the preparse data won't help.
+    // Allow lazy parsing; otherwise cached data won't help.
     bool success = Parser::Parse(&info, true);
-    parse_time = timer.Elapsed();
+    parse_time2 = timer.Elapsed();
     if (!success) {
       fprintf(stderr, "Parsing failed\n");
       return std::make_pair(TimeDelta(), TimeDelta());
     }
   }
-  return std::make_pair(preparse_time, parse_time);
+  return std::make_pair(parse_time1, parse_time2);
 }


@@ -116,7 +109,6 @@
   v8::V8::InitializeICU();
   v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
   Encoding encoding = LATIN1;
-  TestMode test_mode = PreParseAndParse;
   std::vector<std::string> fnames;
   std::string benchmark;
   int repeat = 1;
@@ -127,12 +119,6 @@
       encoding = UTF8;
     } else if (strcmp(argv[i], "--utf16") == 0) {
       encoding = UTF16;
-    } else if (strcmp(argv[i], "--preparse-and-parse") == 0) {
-      test_mode = PreParseAndParse;
-    } else if (strcmp(argv[i], "--preparse") == 0) {
-      test_mode = PreParse;
-    } else if (strcmp(argv[i], "--parse") == 0) {
-      test_mode = Parse;
     } else if (strncmp(argv[i], "--benchmark=", 12) == 0) {
       benchmark = std::string(argv[i]).substr(12);
     } else if (strncmp(argv[i], "--repeat=", 9) == 0) {
@@ -150,20 +136,19 @@
     ASSERT(!context.IsEmpty());
     {
       v8::Context::Scope scope(context);
-      double preparse_total = 0;
-      double parse_total = 0;
+      double first_parse_total = 0;
+      double second_parse_total = 0;
       for (size_t i = 0; i < fnames.size(); i++) {
         std::pair<TimeDelta, TimeDelta> time = RunBaselineParser(
- fnames[i].c_str(), encoding, repeat, isolate, context, test_mode);
-        preparse_total += time.first.InMillisecondsF();
-        parse_total += time.second.InMillisecondsF();
+            fnames[i].c_str(), encoding, repeat, isolate, context);
+        first_parse_total += time.first.InMillisecondsF();
+        second_parse_total += time.second.InMillisecondsF();
       }
       if (benchmark.empty()) benchmark = "Baseline";
-      printf("%s(PreParseRunTime): %.f ms\n", benchmark.c_str(),
-             preparse_total);
-      printf("%s(ParseRunTime): %.f ms\n", benchmark.c_str(), parse_total);
-      printf("%s(RunTime): %.f ms\n", benchmark.c_str(),
-             preparse_total + parse_total);
+      printf("%s(FirstParseRunTime): %.f ms\n", benchmark.c_str(),
+             first_parse_total);
+      printf("%s(SecondParseRunTime): %.f ms\n", benchmark.c_str(),
+             second_parse_total);
     }
   }
   v8::V8::Dispose();

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to