Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : // Test specific cases of the lazy/eager-parse decision.
6 : //
7 : // Note that presently most unit tests for parsing are found in
8 : // cctest/test-parsing.cc.
9 :
10 : #include <unordered_map>
11 :
12 : #include "include/v8.h"
13 : #include "src/api-inl.h"
14 : #include "src/handles-inl.h"
15 : #include "src/isolate.h"
16 : #include "src/objects-inl.h"
17 : #include "src/utils.h"
18 :
19 : #include "test/cctest/cctest.h"
20 :
21 : namespace v8 {
22 : namespace internal {
23 :
24 : namespace {
25 :
26 : // Record the 'compiled' state of all top level functions.
27 15 : void GetTopLevelFunctionInfo(
28 : v8::Local<v8::Script> script,
29 : std::unordered_map<std::string, bool>* is_compiled) {
30 : // Get the v8::internal::Script object from the API v8::Script.
31 : // The API object 'wraps' the compiled top-level function, not the i::Script.
32 : Handle<JSFunction> toplevel_fn = v8::Utils::OpenHandle(*script);
33 : SharedFunctionInfo::ScriptIterator iterator(
34 30 : toplevel_fn->GetIsolate(), Script::cast(toplevel_fn->shared()->script()));
35 :
36 180 : for (SharedFunctionInfo shared = iterator.Next(); !shared.is_null();
37 : shared = iterator.Next()) {
38 150 : std::unique_ptr<char[]> name = String::cast(shared->Name())->ToCString();
39 225 : is_compiled->insert(std::make_pair(name.get(), shared->is_compiled()));
40 : }
41 15 : }
42 :
43 : } // anonymous namespace
44 :
45 28342 : TEST(GetTopLevelFunctionInfo) {
46 5 : if (!FLAG_lazy) return;
47 :
48 : Isolate* isolate = CcTest::i_isolate();
49 : HandleScope scope(isolate);
50 10 : LocalContext env;
51 :
52 5 : const char src[] = "function foo() { var a; }\n";
53 5 : std::unordered_map<std::string, bool> is_compiled;
54 5 : GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
55 :
56 : // Test that our helper function GetTopLevelFunctionInfo does what it claims:
57 : DCHECK(is_compiled.find("foo") != is_compiled.end());
58 : DCHECK(is_compiled.find("bar") == is_compiled.end());
59 : }
60 :
61 28342 : TEST(EagerlyCompileImmediateUseFunctions) {
62 5 : if (!FLAG_lazy) return;
63 :
64 : Isolate* isolate = CcTest::i_isolate();
65 : HandleScope scope(isolate);
66 10 : LocalContext env;
67 :
68 : // Test parenthesized, exclaimed, and regular functions. Make sure these
69 : // occur both intermixed and after each other, to make sure the 'reset'
70 : // mechanism works.
71 : const char src[] =
72 : "function normal() { var a; }\n" // Normal: Should lazy parse.
73 : "(function parenthesized() { var b; })()\n" // Parenthesized: Pre-parse.
74 : "!function exclaimed() { var c; }() \n" // Exclaimed: Pre-parse.
75 : "function normal2() { var d; }\n"
76 : "(function parenthesized2() { var e; })()\n"
77 : "function normal3() { var f; }\n"
78 : "!function exclaimed2() { var g; }() \n"
79 5 : "function normal4() { var h; }\n";
80 :
81 5 : std::unordered_map<std::string, bool> is_compiled;
82 5 : GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
83 :
84 : DCHECK(is_compiled["parenthesized"]);
85 : DCHECK(is_compiled["parenthesized2"]);
86 : DCHECK(is_compiled["exclaimed"]);
87 : DCHECK(is_compiled["exclaimed2"]);
88 : DCHECK(!is_compiled["normal"]);
89 : DCHECK(!is_compiled["normal2"]);
90 : DCHECK(!is_compiled["normal3"]);
91 : DCHECK(!is_compiled["normal4"]);
92 : }
93 :
94 28342 : TEST(CommaFunctionSequence) {
95 5 : if (!FLAG_lazy) return;
96 :
97 : Isolate* isolate = CcTest::i_isolate();
98 : HandleScope scope(isolate);
99 10 : LocalContext env;
100 :
101 5 : const char src[] = "!function a(){}(),function b(){}(),function c(){}();";
102 5 : std::unordered_map<std::string, bool> is_compiled;
103 5 : GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
104 :
105 : DCHECK(is_compiled["a"]);
106 : DCHECK(is_compiled["b"]);
107 : DCHECK(is_compiled["c"]);
108 : }
109 :
110 : } // namespace internal
111 85011 : } // namespace v8
|