LCOV - code coverage report
Current view: top level - test/cctest/compiler - serializer-tester.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 65 65 100.0 %
Date: 2019-03-21 Functions: 18 18 100.0 %

          Line data    Source code
       1             : // Copyright 2019 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             : // Serializer tests don't make sense in lite mode, as it doesn't gather
       6             : // IC feedback.
       7             : #ifndef V8_LITE_MODE
       8             : 
       9             : #include "test/cctest/compiler/serializer-tester.h"
      10             : 
      11             : #include "src/api-inl.h"
      12             : #include "src/compiler/serializer-for-background-compilation.h"
      13             : #include "src/compiler/zone-stats.h"
      14             : #include "src/optimized-compilation-info.h"
      15             : #include "src/zone/zone.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace compiler {
      20             : 
      21          59 : SerializerTester::SerializerTester(const char* source)
      22         118 :     : canonical_(main_isolate()) {
      23             :   // The tests only make sense in the context of concurrent compilation.
      24          59 :   FLAG_concurrent_inlining = true;
      25             :   // The tests don't make sense when optimizations are turned off.
      26          59 :   FLAG_opt = true;
      27             :   // We need the IC to feed it to the serializer.
      28          59 :   FLAG_use_ic = true;
      29             :   // We need manual control over when a given function is optimized.
      30          59 :   FLAG_always_opt = false;
      31             :   // We need allocation of executable memory for the compilation.
      32          59 :   FLAG_jitless = false;
      33             : 
      34          59 :   std::string function_string = "(function() { ";
      35             :   function_string += source;
      36             :   function_string += " })();";
      37             :   Handle<JSFunction> function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
      38             :       *v8::Local<v8::Function>::Cast(CompileRun(function_string.c_str()))));
      39             :   uint32_t flags = i::OptimizedCompilationInfo::kInliningEnabled |
      40             :                    i::OptimizedCompilationInfo::kFunctionContextSpecializing |
      41             :                    i::OptimizedCompilationInfo::kAccessorInliningEnabled |
      42             :                    i::OptimizedCompilationInfo::kLoopPeelingEnabled |
      43             :                    i::OptimizedCompilationInfo::kBailoutOnUninitialized |
      44             :                    i::OptimizedCompilationInfo::kAllocationFoldingEnabled |
      45             :                    i::OptimizedCompilationInfo::kSplittingEnabled |
      46             :                    i::OptimizedCompilationInfo::kAnalyzeEnvironmentLiveness;
      47         118 :   Optimize(function, main_zone(), main_isolate(), flags, &broker_);
      48         118 :   function_ = JSFunctionRef(broker_, function);
      49          59 : }
      50             : 
      51       26068 : TEST(SerializeEmptyFunction) {
      52           5 :   SerializerTester tester("function f() {}; return f;");
      53           5 :   CHECK(tester.function().IsSerializedForCompilation());
      54           5 : }
      55             : 
      56             : // This helper function allows for testing weather an inlinee candidate
      57             : // was properly serialized. It expects that the top-level function (that is
      58             : // run through the SerializerTester) will return its inlinee candidate.
      59          54 : void CheckForSerializedInlinee(const char* source, int argc = 0,
      60             :                                Handle<Object> argv[] = {}) {
      61          54 :   SerializerTester tester(source);
      62          54 :   JSFunctionRef f = tester.function();
      63          54 :   CHECK(f.IsSerializedForCompilation());
      64             : 
      65             :   MaybeHandle<Object> g_obj = Execution::Call(
      66         108 :       tester.isolate(), tester.function().object(),
      67         162 :       tester.isolate()->factory()->undefined_value(), argc, argv);
      68             :   Handle<Object> g;
      69          54 :   CHECK(g_obj.ToHandle(&g));
      70             : 
      71             :   Handle<JSFunction> g_func = Handle<JSFunction>::cast(g);
      72             :   SharedFunctionInfoRef g_sfi(tester.broker(),
      73             :                               handle(g_func->shared(), tester.isolate()));
      74             :   FeedbackVectorRef g_fv(tester.broker(),
      75         108 :                          handle(g_func->feedback_vector(), tester.isolate()));
      76          54 :   CHECK(g_sfi.IsSerializedForCompilation(g_fv));
      77          54 : }
      78             : 
      79       26067 : TEST(SerializeInlinedClosure) {
      80             :   CheckForSerializedInlinee(
      81             :       "function f() {"
      82             :       "  return (function g(){ return g; })();"
      83           4 :       "}; f(); return f;");
      84           4 : }
      85             : 
      86       26067 : TEST(SerializeInlinedFunction) {
      87             :   CheckForSerializedInlinee(
      88             :       "function g() {};"
      89             :       "function f() {"
      90             :       "  g(); return g;"
      91           4 :       "}; f(); return f;");
      92           4 : }
      93             : 
      94       26067 : TEST(SerializeCallUndefinedReceiver) {
      95             :   CheckForSerializedInlinee(
      96             :       "function g(a,b,c) {};"
      97             :       "function f() {"
      98             :       "  g(1,2,3); return g;"
      99           4 :       "}; f(); return f;");
     100           4 : }
     101             : 
     102       26067 : TEST(SerializeCallUndefinedReceiver2) {
     103             :   CheckForSerializedInlinee(
     104             :       "function g(a,b) {};"
     105             :       "function f() {"
     106             :       "  g(1,2); return g;"
     107           4 :       "}; f(); return f;");
     108           4 : }
     109             : 
     110       26067 : TEST(SerializeCallProperty) {
     111             :   CheckForSerializedInlinee(
     112             :       "let obj = {"
     113             :       "  g: function g(a,b,c) {}"
     114             :       "};"
     115             :       "function f() {"
     116             :       "  obj.g(1,2,3); return obj.g;"
     117           4 :       "}; f(); return f;");
     118           4 : }
     119             : 
     120       26067 : TEST(SerializeCallProperty2) {
     121             :   CheckForSerializedInlinee(
     122             :       "let obj = {"
     123             :       "  g: function g(a,b) {}"
     124             :       "};"
     125             :       "function f() {"
     126             :       "  obj.g(1,2); return obj.g;"
     127           4 :       "}; f(); return f;");
     128           4 : }
     129             : 
     130       26067 : TEST(SerializeCallAnyReceiver) {
     131             :   CheckForSerializedInlinee(
     132             :       "let obj = {"
     133             :       "  g: function g() {}"
     134             :       "};"
     135             :       "function f() {"
     136             :       "  with(obj) {"
     137             :       "    g(); return g;"
     138             :       "  };"
     139             :       "};"
     140           4 :       "f(); return f;");
     141           4 : }
     142             : 
     143       26067 : TEST(SerializeCallWithSpread) {
     144             :   CheckForSerializedInlinee(
     145             :       "function g(args) {};"
     146             :       "const arr = [1,2,3];"
     147             :       "function f() {"
     148             :       "  g(...arr); return g;"
     149           4 :       "}; f(); return f;");
     150           4 : }
     151             : 
     152             : // The following test causes the CallIC of `g` to turn megamorphic,
     153             : // thus allowing us to test if we forward arguments hints (`callee` in this
     154             : // example) and correctly serialize the inlining candidate `j`.
     155       26067 : TEST(SerializeCallArguments) {
     156             :   CheckForSerializedInlinee(
     157             :       "function g(callee) { callee(); };"
     158             :       "function h() {};"
     159             :       "function i() {};"
     160             :       "g(h); g(i);"
     161             :       "function f() {"
     162             :       "  function j() {};"
     163             :       "  g(j);"
     164             :       "  return j;"
     165           4 :       "}; f(); return f;");
     166           4 : }
     167             : 
     168       26067 : TEST(SerializeConstruct) {
     169             :   CheckForSerializedInlinee(
     170             :       "function g() {};"
     171             :       "function f() {"
     172             :       "  new g(); return g;"
     173           4 :       "}; f(); return f;");
     174           4 : }
     175             : 
     176       26067 : TEST(SerializeConstructWithSpread) {
     177             :   CheckForSerializedInlinee(
     178             :       "function g(a, b, c) {};"
     179             :       "const arr = [1, 2];"
     180             :       "function f() {"
     181             :       "  new g(0, ...arr); return g;"
     182           4 :       "}; f(); return f;");
     183           4 : }
     184             : 
     185       26068 : TEST(SerializeConditionalJump) {
     186             :   CheckForSerializedInlinee(
     187             :       "function g(callee) { callee(); };"
     188             :       "function h() {};"
     189             :       "function i() {};"
     190             :       "let a = true;"
     191             :       "g(h); g(i);"
     192             :       "function f() {"
     193             :       "  function q() {};"
     194             :       "  if (a) g(q);"
     195             :       "  return q;"
     196           5 :       "}; f(); return f;");
     197           5 : }
     198             : 
     199       26068 : TEST(SerializeUnconditionalJump) {
     200             :   CheckForSerializedInlinee(
     201             :       "function g(callee) { callee(); };"
     202             :       "function h() {};"
     203             :       "function i() {};"
     204             :       "let a = false;"
     205             :       "g(h); g(i);"
     206             :       "function f() {"
     207             :       "  function p() {};"
     208             :       "  function q() {};"
     209             :       "  if (a) g(q);"
     210             :       "  else g(p);"
     211             :       "  return p;"
     212           5 :       "}; f(); return f;");
     213           5 : }
     214             : 
     215             : }  // namespace compiler
     216             : }  // namespace internal
     217       78189 : }  // namespace v8
     218             : 
     219             : #endif  // V8_LITE_MODE

Generated by: LCOV version 1.10