LCOV - code coverage report
Current view: top level - test/unittests/api - isolate-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 56 56 100.0 %
Date: 2019-03-21 Functions: 14 18 77.8 %

          Line data    Source code
       1             : // Copyright 2017 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             : #include "testing/gtest/include/gtest/gtest.h"
       6             : 
       7             : #include "include/libplatform/libplatform.h"
       8             : #include "include/v8-platform.h"
       9             : #include "include/v8.h"
      10             : #include "src/base/macros.h"
      11             : #include "src/base/platform/semaphore.h"
      12             : #include "src/base/template-utils.h"
      13             : #include "src/execution.h"
      14             : #include "src/isolate.h"
      15             : #include "src/v8.h"
      16             : #include "test/unittests/test-utils.h"
      17             : 
      18             : namespace v8 {
      19             : 
      20             : typedef TestWithIsolate IsolateTest;
      21             : 
      22             : namespace {
      23             : 
      24             : class MemoryPressureTask : public v8::Task {
      25             :  public:
      26             :   MemoryPressureTask(Isolate* isolate, base::Semaphore* semaphore)
      27           1 :       : isolate_(isolate), semaphore_(semaphore) {}
      28           2 :   ~MemoryPressureTask() override = default;
      29             : 
      30             :   // v8::Task implementation.
      31           1 :   void Run() override {
      32           1 :     isolate_->MemoryPressureNotification(MemoryPressureLevel::kCritical);
      33           1 :     semaphore_->Signal();
      34           1 :   }
      35             : 
      36             :  private:
      37             :   Isolate* isolate_;
      38             :   base::Semaphore* semaphore_;
      39             : 
      40             :   DISALLOW_COPY_AND_ASSIGN(MemoryPressureTask);
      41             : };
      42             : 
      43             : }  // namespace
      44             : 
      45             : // Check that triggering a memory pressure notification on the isolate thread
      46             : // doesn't request a GC interrupt.
      47       15373 : TEST_F(IsolateTest, MemoryPressureNotificationForeground) {
      48             :   internal::Isolate* i_isolate =
      49             :       reinterpret_cast<internal::Isolate*>(isolate());
      50             : 
      51           2 :   ASSERT_FALSE(i_isolate->stack_guard()->CheckGC());
      52           1 :   isolate()->MemoryPressureNotification(MemoryPressureLevel::kCritical);
      53           2 :   ASSERT_FALSE(i_isolate->stack_guard()->CheckGC());
      54             : }
      55             : 
      56             : // Check that triggering a memory pressure notification on an background thread
      57             : // requests a GC interrupt.
      58       15373 : TEST_F(IsolateTest, MemoryPressureNotificationBackground) {
      59             :   internal::Isolate* i_isolate =
      60             :       reinterpret_cast<internal::Isolate*>(isolate());
      61             : 
      62           2 :   base::Semaphore semaphore(0);
      63             : 
      64           2 :   internal::V8::GetCurrentPlatform()->CallOnWorkerThread(
      65           2 :       base::make_unique<MemoryPressureTask>(isolate(), &semaphore));
      66             : 
      67           1 :   semaphore.Wait();
      68             : 
      69           1 :   ASSERT_TRUE(i_isolate->stack_guard()->CheckGC());
      70           1 :   v8::platform::PumpMessageLoop(internal::V8::GetCurrentPlatform(), isolate());
      71             : }
      72             : 
      73             : using IncumbentContextTest = TestWithIsolate;
      74             : 
      75             : // Check that Isolate::GetIncumbentContext() returns the correct one in basic
      76             : // scenarios.
      77       15373 : TEST_F(IncumbentContextTest, Basic) {
      78          13 :   auto Str = [&](const char* s) {
      79          13 :     return String::NewFromUtf8(isolate(), s, NewStringType::kNormal)
      80             :         .ToLocalChecked();
      81          14 :   };
      82           9 :   auto Run = [&](Local<Context> context, const char* script) {
      83             :     Context::Scope scope(context);
      84           9 :     return Script::Compile(context, Str(script))
      85             :         .ToLocalChecked()
      86           9 :         ->Run(context)
      87           9 :         .ToLocalChecked();
      88             :   };
      89             : 
      90             :   // Set up the test environment; three contexts with getIncumbentGlobal()
      91             :   // function.
      92             :   Local<FunctionTemplate> get_incumbent_global = FunctionTemplate::New(
      93           8 :       isolate(), [](const FunctionCallbackInfo<Value>& info) {
      94             :         Local<Context> incumbent_context =
      95           4 :             info.GetIsolate()->GetIncumbentContext();
      96           4 :         info.GetReturnValue().Set(incumbent_context->Global());
      97           9 :       });
      98           1 :   Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate());
      99           2 :   global_template->Set(Str("getIncumbentGlobal"), get_incumbent_global);
     100             : 
     101           1 :   Local<Context> context_a = Context::New(isolate(), nullptr, global_template);
     102           1 :   Local<Context> context_b = Context::New(isolate(), nullptr, global_template);
     103           1 :   Local<Context> context_c = Context::New(isolate(), nullptr, global_template);
     104           1 :   Local<Object> global_a = context_a->Global();
     105           1 :   Local<Object> global_b = context_b->Global();
     106           1 :   Local<Object> global_c = context_c->Global();
     107             : 
     108           1 :   Local<String> security_token = Str("security_token");
     109           1 :   context_a->SetSecurityToken(security_token);
     110           1 :   context_b->SetSecurityToken(security_token);
     111           1 :   context_c->SetSecurityToken(security_token);
     112             : 
     113           3 :   global_a->Set(context_a, Str("b"), global_b).ToChecked();
     114           3 :   global_b->Set(context_b, Str("c"), global_c).ToChecked();
     115             : 
     116             :   // Test scenario 2: A -> B -> C, then the incumbent is C.
     117           1 :   Run(context_a, "funcA = function() { return b.funcB(); }");
     118           1 :   Run(context_b, "funcB = function() { return c.getIncumbentGlobal(); }");
     119             :   // Without BackupIncumbentScope.
     120           2 :   EXPECT_EQ(global_b, Run(context_a, "funcA()"));
     121             :   {
     122             :     // With BackupIncumbentScope.
     123           2 :     Context::BackupIncumbentScope backup_incumbent(context_a);
     124           2 :     EXPECT_EQ(global_b, Run(context_a, "funcA()"));
     125             :   }
     126             : 
     127             :   // Test scenario 2: A -> B -> C -> C, then the incumbent is C.
     128           1 :   Run(context_a, "funcA = function() { return b.funcB(); }");
     129           1 :   Run(context_b, "funcB = function() { return c.funcC(); }");
     130           1 :   Run(context_c, "funcC = function() { return getIncumbentGlobal(); }");
     131             :   // Without BackupIncumbentScope.
     132           2 :   EXPECT_EQ(global_c, Run(context_a, "funcA()"));
     133             :   {
     134             :     // With BackupIncumbentScope.
     135           2 :     Context::BackupIncumbentScope backup_incumbent(context_a);
     136           2 :     EXPECT_EQ(global_c, Run(context_a, "funcA()"));
     137             :   }
     138           1 : }
     139             : 
     140        9222 : }  // namespace v8

Generated by: LCOV version 1.10