Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: test/cctest/test-parsing.cc

Issue 261273003: Remove symbol preparse data altogether. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/scanner.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 v8::ScriptCompiler::Source bad_source( 270 v8::ScriptCompiler::Source bad_source(
271 v8_str(bad_code), new v8::ScriptCompiler::CachedData( 271 v8_str(bad_code), new v8::ScriptCompiler::CachedData(
272 cached_data->data, cached_data->length)); 272 cached_data->data, cached_data->length));
273 v8::Local<v8::Value> result = 273 v8::Local<v8::Value> result =
274 v8::ScriptCompiler::Compile(isolate, &bad_source)->Run(); 274 v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
275 CHECK(result->IsInt32()); 275 CHECK(result->IsInt32());
276 CHECK_EQ(25, result->Int32Value()); 276 CHECK_EQ(25, result->Int32Value());
277 } 277 }
278 278
279 279
280 TEST(PreparseSymbolDataIsUsed) {
281 // This tests that we actually do use the symbol data generated by the
282 // preparser.
283
284 // Only do one compilation pass in this test (otherwise we will parse the
285 // source code again without preparse data and it will fail).
286 i::FLAG_crankshaft = false;
287
288 // Make preparsing work for short scripts.
289 i::FLAG_min_preparse_length = 0;
290
291 v8::Isolate* isolate = CcTest::isolate();
292 v8::HandleScope handles(isolate);
293 v8::Local<v8::Context> context = v8::Context::New(isolate);
294 v8::Context::Scope context_scope(context);
295 int marker;
296 CcTest::i_isolate()->stack_guard()->SetStackLimit(
297 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
298
299 // Note that the ( before function makes the function not lazily compiled.
300 const char* good_code =
301 "(function weird() { var foo = 26; return foo; })()";
302
303 // Insert an undefined identifier. If the preparser data is used, the symbol
304 // stream is used instead, and this identifier resolves to "foo".
305 const char* bad_code =
306 "(function weird() { var foo = 26; return wut; })()";
307
308 v8::ScriptCompiler::Source good_source(v8_str(good_code));
309 v8::ScriptCompiler::Compile(isolate, &good_source,
310 v8::ScriptCompiler::kProduceDataToCache);
311
312 const v8::ScriptCompiler::CachedData* cached_data =
313 good_source.GetCachedData();
314 CHECK(cached_data->data != NULL);
315 CHECK_GT(cached_data->length, 0);
316
317 // Now compile the erroneous code with the good preparse data. If the preparse
318 // data is used, we will see a second occurrence of "foo" instead of the
319 // unknown "wut".
320 v8::ScriptCompiler::Source bad_source(
321 v8_str(bad_code), new v8::ScriptCompiler::CachedData(
322 cached_data->data, cached_data->length));
323 v8::Local<v8::Value> result =
324 v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
325 CHECK(result->IsInt32());
326 CHECK_EQ(26, result->Int32Value());
327 }
328
329
330 TEST(StandAlonePreParser) { 280 TEST(StandAlonePreParser) {
331 v8::V8::Initialize(); 281 v8::V8::Initialize();
332 282
333 int marker; 283 int marker;
334 CcTest::i_isolate()->stack_guard()->SetStackLimit( 284 CcTest::i_isolate()->stack_guard()->SetStackLimit(
335 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 285 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
336 286
337 const char* programs[] = { 287 const char* programs[] = {
338 "{label: 42}", 288 "{label: 42}",
339 "var x = 42;", 289 "var x = 42;",
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 378
429 { 379 {
430 const char* source = "var myo = {1: \"foo\"}; myo[1];"; 380 const char* source = "var myo = {1: \"foo\"}; myo[1];";
431 v8::Local<v8::Value> result = PreCompileCompileRun(source); 381 v8::Local<v8::Value> result = PreCompileCompileRun(source);
432 CHECK(result->IsString()); 382 CHECK(result->IsString());
433 v8::String::Utf8Value utf8(result); 383 v8::String::Utf8Value utf8(result);
434 CHECK_EQ("foo", *utf8); 384 CHECK_EQ("foo", *utf8);
435 } 385 }
436 } 386 }
437 387
438 namespace v8 {
439 namespace internal {
440
441 struct CompleteParserRecorderFriend {
442 static void FakeWritingSymbolIdInPreParseData(CompleteParserRecorder* log,
443 int number) {
444 log->WriteNumber(number);
445 if (log->symbol_id_ < number + 1) {
446 log->symbol_id_ = number + 1;
447 }
448 }
449 };
450
451 }
452 }
453
454
455 TEST(StoringNumbersInPreParseData) {
456 // Symbol IDs are split into chunks of 7 bits for storing. This is a
457 // regression test for a bug where a symbol id was incorrectly stored if some
458 // of the chunks in the middle were all zeros.
459 typedef i::CompleteParserRecorderFriend F;
460 i::CompleteParserRecorder log;
461 for (int i = 0; i < 18; ++i) {
462 F::FakeWritingSymbolIdInPreParseData(&log, 1 << i);
463 }
464 for (int i = 1; i < 18; ++i) {
465 F::FakeWritingSymbolIdInPreParseData(&log, (1 << i) + 1);
466 }
467 for (int i = 6; i < 18; ++i) {
468 F::FakeWritingSymbolIdInPreParseData(&log, (3 << i) + (5 << (i - 6)));
469 }
470 i::Vector<unsigned> store = log.ExtractData();
471 i::ScriptData script_data(store);
472 script_data.Initialize();
473 // Check that we get the same symbols back.
474 for (int i = 0; i < 18; ++i) {
475 CHECK_EQ(1 << i, script_data.GetSymbolIdentifier());
476 }
477 for (int i = 1; i < 18; ++i) {
478 CHECK_EQ((1 << i) + 1, script_data.GetSymbolIdentifier());
479 }
480 for (int i = 6; i < 18; ++i) {
481 CHECK_EQ((3 << i) + (5 << (i - 6)), script_data.GetSymbolIdentifier());
482 }
483 }
484
485 388
486 TEST(RegressChromium62639) { 389 TEST(RegressChromium62639) {
487 v8::V8::Initialize(); 390 v8::V8::Initialize();
488 i::Isolate* isolate = CcTest::i_isolate(); 391 i::Isolate* isolate = CcTest::i_isolate();
489 392
490 int marker; 393 int marker;
491 isolate->stack_guard()->SetStackLimit( 394 isolate->stack_guard()->SetStackLimit(
492 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 395 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
493 396
494 const char* program = "var x = 'something';\n" 397 const char* program = "var x = 'something';\n"
(...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after
2065 v8::V8::Initialize(); 1968 v8::V8::Initialize();
2066 v8::Isolate* isolate = CcTest::isolate(); 1969 v8::Isolate* isolate = CcTest::isolate();
2067 v8::HandleScope handles(isolate); 1970 v8::HandleScope handles(isolate);
2068 1971
2069 int marker; 1972 int marker;
2070 CcTest::i_isolate()->stack_guard()->SetStackLimit( 1973 CcTest::i_isolate()->stack_guard()->SetStackLimit(
2071 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 1974 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
2072 1975
2073 struct TestCase { 1976 struct TestCase {
2074 const char* program; 1977 const char* program;
2075 int symbols;
2076 int functions; 1978 int functions;
2077 } test_cases[] = { 1979 } test_cases[] = {
2078 // Labels and variables are recorded as symbols. 1980 // No functions.
2079 {"{label: 42}", 1, 0}, {"{label: 42; label2: 43}", 2, 0}, 1981 {"var x = 42;", 0},
2080 {"var x = 42;", 1, 0}, {"var x = 42, y = 43;", 2, 0}, 1982 // Functions.
2081 {"var x = {y: 1};", 2, 0}, 1983 {"function foo() {}", 1}, {"function foo() {} function bar() {}", 2},
2082 {"var x = {}; x.y = 1", 2, 0}, 1984 // Getter / setter functions are recorded as functions if they're on the top
2083 // "get" is recorded as a symbol too. 1985 // level.
2084 {"var x = {get foo(){} };", 3, 1}, 1986 {"var x = {get foo(){} };", 1},
2085 // When keywords are used as identifiers, they're logged as symbols, too: 1987 // Functions insize lazy functions are not recorded.
2086 {"var x = {if: 1};", 2, 0}, 1988 {"function lazy() { function a() {} function b() {} function c() {} }", 1},
2087 {"var x = {}; x.if = 1", 2, 0}, 1989 {"function lazy() { var x = {get foo(){} } }", 1},
2088 {"var x = {get if(){} };", 3, 1}, 1990 {NULL, 0}
2089 // Functions
2090 {"function foo() {}", 1, 1}, {"function foo() {} function bar() {}", 2, 2},
2091 // Labels, variables and functions insize lazy functions are not recorded.
2092 {"function lazy() { var a, b, c; }", 1, 1},
2093 {"function lazy() { a: 1; b: 2; c: 3; }", 1, 1},
2094 {"function lazy() { function a() {} function b() {} function c() {} }", 1,
2095 1},
2096 {NULL, 0, 0}
2097 }; 1991 };
2098 1992
2099 for (int i = 0; test_cases[i].program; i++) { 1993 for (int i = 0; test_cases[i].program; i++) {
2100 const char* program = test_cases[i].program; 1994 const char* program = test_cases[i].program;
2101 i::Factory* factory = CcTest::i_isolate()->factory(); 1995 i::Factory* factory = CcTest::i_isolate()->factory();
2102 i::Handle<i::String> source = 1996 i::Handle<i::String> source =
2103 factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked(); 1997 factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
2104 i::Handle<i::Script> script = factory->NewScript(source); 1998 i::Handle<i::Script> script = factory->NewScript(source);
2105 i::CompilationInfoWithZone info(script); 1999 i::CompilationInfoWithZone info(script);
2106 i::ScriptData* data = NULL; 2000 i::ScriptData* data = NULL;
2107 info.SetCachedData(&data, i::PRODUCE_CACHED_DATA); 2001 info.SetCachedData(&data, i::PRODUCE_CACHED_DATA);
2108 i::Parser::Parse(&info, true); 2002 i::Parser::Parse(&info, true);
2109 CHECK(data); 2003 CHECK(data);
2110 CHECK(!data->HasError()); 2004 CHECK(!data->HasError());
2111 2005
2112 if (data->symbol_count() != test_cases[i].symbols) {
2113 i::OS::Print(
2114 "Expected preparse data for program:\n"
2115 "\t%s\n"
2116 "to contain %d symbols, however, received %d symbols.\n",
2117 program, test_cases[i].symbols, data->symbol_count());
2118 CHECK(false);
2119 }
2120 if (data->function_count() != test_cases[i].functions) { 2006 if (data->function_count() != test_cases[i].functions) {
2121 i::OS::Print( 2007 i::OS::Print(
2122 "Expected preparse data for program:\n" 2008 "Expected preparse data for program:\n"
2123 "\t%s\n" 2009 "\t%s\n"
2124 "to contain %d functions, however, received %d functions.\n", 2010 "to contain %d functions, however, received %d functions.\n",
2125 program, test_cases[i].functions, 2011 program, test_cases[i].functions,
2126 data->function_count()); 2012 data->function_count());
2127 CHECK(false); 2013 CHECK(false);
2128 } 2014 }
2129 } 2015 }
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
2566 RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError); 2452 RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError);
2567 RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment, 2453 RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment,
2568 kError); 2454 kError);
2569 2455
2570 RunParserSyncTest(prefix_context_data, good_statement_data, kSuccess); 2456 RunParserSyncTest(prefix_context_data, good_statement_data, kSuccess);
2571 RunParserSyncTest(prefix_context_data, bad_statement_data_common, kError); 2457 RunParserSyncTest(prefix_context_data, bad_statement_data_common, kError);
2572 2458
2573 RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess); 2459 RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess);
2574 RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError); 2460 RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError);
2575 } 2461 }
OLDNEW
« no previous file with comments | « src/scanner.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698