LCOV - code coverage report
Current view: top level - test/cctest - cctest.h (source / functions) Hit Total Coverage
Test: app.info Lines: 165 186 88.7 %
Date: 2019-02-19 Functions: 41 55 74.5 %

          Line data    Source code
       1             : // Copyright 2008 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #ifndef CCTEST_H_
      29             : #define CCTEST_H_
      30             : 
      31             : #include <memory>
      32             : 
      33             : #include "include/libplatform/libplatform.h"
      34             : #include "include/v8-platform.h"
      35             : #include "src/base/enum-set.h"
      36             : #include "src/debug/debug-interface.h"
      37             : #include "src/flags.h"
      38             : #include "src/heap/factory.h"
      39             : #include "src/isolate.h"
      40             : #include "src/objects.h"
      41             : #include "src/register-configuration.h"
      42             : #include "src/v8.h"
      43             : #include "src/zone/accounting-allocator.h"
      44             : 
      45             : namespace v8 {
      46             : namespace base {
      47             : 
      48             : class RandomNumberGenerator;
      49             : 
      50             : }  // namespace base
      51             : 
      52             : namespace internal {
      53             : 
      54             : const auto GetRegConfig = RegisterConfiguration::Default;
      55             : 
      56             : class HandleScope;
      57             : class Zone;
      58             : 
      59             : namespace compiler {
      60             : 
      61             : class JSHeapBroker;
      62             : 
      63             : }  // namespace compiler
      64             : 
      65             : }  // namespace internal
      66             : 
      67             : }  // namespace v8
      68             : 
      69             : #ifndef TEST
      70             : #define TEST(Name)                                                      \
      71             :   static void Test##Name();                                             \
      72             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, true); \
      73             :   static void Test##Name()
      74             : #endif
      75             : 
      76             : #ifndef UNINITIALIZED_TEST
      77             : #define UNINITIALIZED_TEST(Name)                                         \
      78             :   static void Test##Name();                                              \
      79             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, false); \
      80             :   static void Test##Name()
      81             : #endif
      82             : 
      83             : #ifndef DISABLED_TEST
      84             : #define DISABLED_TEST(Name)                                              \
      85             :   static void Test##Name();                                              \
      86             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, false, true); \
      87             :   static void Test##Name()
      88             : #endif
      89             : 
      90             : #define EXTENSION_LIST(V)                                                      \
      91             :   V(GC_EXTENSION,       "v8/gc")                                               \
      92             :   V(PRINT_EXTENSION,    "v8/print")                                            \
      93             :   V(PROFILER_EXTENSION, "v8/profiler")                                         \
      94             :   V(TRACE_EXTENSION,    "v8/trace")
      95             : 
      96             : #define DEFINE_EXTENSION_ID(Name, Ident) Name##_ID,
      97             : enum CcTestExtensionId { EXTENSION_LIST(DEFINE_EXTENSION_ID) kMaxExtensions };
      98             : #undef DEFINE_EXTENSION_ID
      99             : 
     100             : using CcTestExtensionFlags = v8::base::EnumSet<CcTestExtensionId>;
     101             : 
     102             : #define DEFINE_EXTENSION_NAME(Name, Ident) Ident,
     103             : static constexpr const char* kExtensionName[kMaxExtensions] = {
     104             :     EXTENSION_LIST(DEFINE_EXTENSION_NAME)};
     105             : #undef DEFINE_EXTENSION_NAME
     106             : 
     107             : class CcTest {
     108             :  public:
     109             :   typedef void (TestFunction)();
     110             :   CcTest(TestFunction* callback, const char* file, const char* name,
     111             :          bool enabled, bool initialize);
     112   302168250 :   ~CcTest() { i::DeleteArray(file_); }
     113             :   void Run();
     114       37416 :   static CcTest* last() { return last_; }
     115             :   CcTest* prev() { return prev_; }
     116             :   const char* file() { return file_; }
     117             :   const char* name() { return name_; }
     118             :   bool enabled() { return enabled_; }
     119             : 
     120    15849877 :   static v8::Isolate* isolate() {
     121    15849877 :     CHECK_NOT_NULL(isolate_);
     122             :     v8::base::Relaxed_Store(&isolate_used_, 1);
     123    15849877 :     return isolate_;
     124             :   }
     125             : 
     126    12557558 :   static i::Isolate* InitIsolateOnce() {
     127    12557558 :     if (!initialize_called_) InitializeVM();
     128    12557558 :     return i_isolate();
     129             :   }
     130             : 
     131             :   static i::Isolate* i_isolate() {
     132    15655675 :     return reinterpret_cast<i::Isolate*>(isolate());
     133             :   }
     134             : 
     135             :   static i::Heap* heap();
     136             : 
     137             :   static void CollectGarbage(i::AllocationSpace space);
     138             :   static void CollectAllGarbage(i::Isolate* isolate = nullptr);
     139             :   static void CollectAllAvailableGarbage(i::Isolate* isolate = nullptr);
     140             :   static void PreciseCollectAllGarbage(i::Isolate* isolate = nullptr);
     141             : 
     142             :   static v8::base::RandomNumberGenerator* random_number_generator();
     143             : 
     144             :   static v8::Local<v8::Object> global();
     145             : 
     146             :   static v8::ArrayBuffer::Allocator* array_buffer_allocator() {
     147        1530 :     return allocator_;
     148             :   }
     149             : 
     150             :   static void set_array_buffer_allocator(
     151             :       v8::ArrayBuffer::Allocator* allocator) {
     152       25875 :     allocator_ = allocator;
     153             :   }
     154             : 
     155             :   // TODO(dcarney): Remove.
     156             :   // This must be called first in a test.
     157             :   static void InitializeVM();
     158             : 
     159             :   // Only for UNINITIALIZED_TESTs
     160             :   static void DisableAutomaticDispose();
     161             : 
     162             :   // Helper function to configure a context.
     163             :   // Must be in a HandleScope.
     164             :   static v8::Local<v8::Context> NewContext(
     165             :       v8::Isolate* isolate = CcTest::isolate()) {
     166             :     return NewContext({}, isolate);
     167             :   }
     168             :   static v8::Local<v8::Context> NewContext(
     169             :       CcTestExtensionFlags extension_flags,
     170             :       v8::Isolate* isolate = CcTest::isolate());
     171             : 
     172             :   static void TearDown();
     173             : 
     174             :  private:
     175             :   friend int main(int argc, char** argv);
     176             :   TestFunction* callback_;
     177             :   const char* file_;
     178             :   const char* name_;
     179             :   bool enabled_;
     180             :   bool initialize_;
     181             :   CcTest* prev_;
     182             :   static CcTest* last_;
     183             :   static v8::ArrayBuffer::Allocator* allocator_;
     184             :   static v8::Isolate* isolate_;
     185             :   static bool initialize_called_;
     186             :   static v8::base::Atomic32 isolate_used_;
     187             : };
     188             : 
     189             : // Switches between all the Api tests using the threading support.
     190             : // In order to get a surprising but repeatable pattern of thread
     191             : // switching it has extra semaphores to control the order in which
     192             : // the tests alternate, not relying solely on the big V8 lock.
     193             : //
     194             : // A test is augmented with calls to ApiTestFuzzer::Fuzz() in its
     195             : // callbacks.  This will have no effect when we are not running the
     196             : // thread fuzzing test.  In the thread fuzzing test it will
     197             : // pseudorandomly select a successor thread and switch execution
     198             : // to that thread, suspending the current test.
     199             : class ApiTestFuzzer: public v8::base::Thread {
     200             :  public:
     201             :   void CallTest();
     202             : 
     203             :   // The ApiTestFuzzer is also a Thread, so it has a Run method.
     204             :   void Run() override;
     205             : 
     206             :   enum PartOfTest {
     207             :     FIRST_PART,
     208             :     SECOND_PART,
     209             :     THIRD_PART,
     210             :     FOURTH_PART,
     211             :     FIFTH_PART,
     212             :     SIXTH_PART,
     213             :     SEVENTH_PART,
     214             :     EIGHTH_PART,
     215             :     LAST_PART = EIGHTH_PART
     216             :   };
     217             : 
     218             :   static void SetUp(PartOfTest part);
     219             :   static void RunAllTests();
     220             :   static void TearDown();
     221             :   // This method switches threads if we are running the Threading test.
     222             :   // Otherwise it does nothing.
     223             :   static void Fuzz();
     224             : 
     225             :  private:
     226         468 :   explicit ApiTestFuzzer(int num)
     227             :       : Thread(Options("ApiTestFuzzer")),
     228             :         test_number_(num),
     229             :         gate_(0),
     230         468 :         active_(true) {}
     231           0 :   ~ApiTestFuzzer() override = default;
     232             : 
     233             :   static bool fuzzing_;
     234             :   static int tests_being_run_;
     235             :   static int current_;
     236             :   static int active_tests_;
     237             :   static bool NextThread();
     238             :   int test_number_;
     239             :   v8::base::Semaphore gate_;
     240             :   bool active_;
     241             :   void ContextSwitch();
     242             :   static int GetNextTestNumber();
     243             :   static v8::base::Semaphore all_tests_done_;
     244             : };
     245             : 
     246             : 
     247             : #define THREADED_TEST(Name)                                          \
     248             :   static void Test##Name();                                          \
     249             :   RegisterThreadedTest register_##Name(Test##Name, #Name);           \
     250             :   /* */ TEST(Name)
     251             : 
     252             : class RegisterThreadedTest {
     253             :  public:
     254             :   explicit RegisterThreadedTest(CcTest::TestFunction* callback,
     255             :                                 const char* name)
     256    12109500 :       : fuzzer_(nullptr), callback_(callback), name_(name) {
     257    12109500 :     prev_ = first_;
     258    12109500 :     first_ = this;
     259    12109500 :     count_++;
     260             :   }
     261     3317866 :   static int count() { return count_; }
     262     3314106 :   static RegisterThreadedTest* nth(int i) {
     263     3314106 :     CHECK(i < count());
     264     3314106 :     RegisterThreadedTest* current = first_;
     265   102535447 :     while (i > 0) {
     266    95907235 :       i--;
     267    95907235 :       current = current->prev_;
     268             :     }
     269     3314106 :     return current;
     270             :   }
     271             :   CcTest::TestFunction* callback() { return callback_; }
     272             :   ApiTestFuzzer* fuzzer_;
     273             :   const char* name() { return name_; }
     274             : 
     275             :  private:
     276             :   static RegisterThreadedTest* first_;
     277             :   static int count_;
     278             :   CcTest::TestFunction* callback_;
     279             :   RegisterThreadedTest* prev_;
     280             :   const char* name_;
     281             : };
     282             : 
     283             : // A LocalContext holds a reference to a v8::Context.
     284             : class LocalContext {
     285             :  public:
     286             :   LocalContext(v8::Isolate* isolate,
     287             :                v8::ExtensionConfiguration* extensions = nullptr,
     288             :                v8::Local<v8::ObjectTemplate> global_template =
     289             :                    v8::Local<v8::ObjectTemplate>(),
     290        2462 :                v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) {
     291        2462 :     Initialize(isolate, extensions, global_template, global_object);
     292             :   }
     293             : 
     294        9307 :   LocalContext(v8::ExtensionConfiguration* extensions = nullptr,
     295             :                v8::Local<v8::ObjectTemplate> global_template =
     296             :                    v8::Local<v8::ObjectTemplate>(),
     297        9307 :                v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) {
     298        9307 :     Initialize(CcTest::isolate(), extensions, global_template, global_object);
     299        9307 :   }
     300             : 
     301             :   virtual ~LocalContext();
     302             : 
     303             :   v8::Context* operator->() {
     304      112494 :     return *reinterpret_cast<v8::Context**>(&context_);
     305             :   }
     306             :   v8::Context* operator*() { return operator->(); }
     307             :   bool IsReady() { return !context_.IsEmpty(); }
     308             : 
     309      187850 :   v8::Local<v8::Context> local() {
     310      375700 :     return v8::Local<v8::Context>::New(isolate_, context_);
     311             :   }
     312             : 
     313             :  private:
     314             :   void Initialize(v8::Isolate* isolate, v8::ExtensionConfiguration* extensions,
     315             :                   v8::Local<v8::ObjectTemplate> global_template,
     316             :                   v8::Local<v8::Value> global_object);
     317             : 
     318             :   v8::Persistent<v8::Context> context_;
     319             :   v8::Isolate* isolate_;
     320             : };
     321             : 
     322             : 
     323       25997 : static inline uint16_t* AsciiToTwoByteString(const char* source) {
     324       25997 :   int array_length = i::StrLength(source) + 1;
     325       25997 :   uint16_t* converted = i::NewArray<uint16_t>(array_length);
     326       25997 :   for (int i = 0; i < array_length; i++) converted[i] = source[i];
     327       25997 :   return converted;
     328             : }
     329             : 
     330             : template <typename T>
     331          70 : static inline i::Handle<T> GetGlobal(const char* name) {
     332             :   i::Isolate* isolate = CcTest::i_isolate();
     333             :   i::Handle<i::String> str_name =
     334          70 :       isolate->factory()->InternalizeUtf8String(name);
     335             : 
     336             :   i::Handle<i::Object> value =
     337         140 :       i::Object::GetProperty(isolate, isolate->global_object(), str_name)
     338         140 :           .ToHandleChecked();
     339          70 :   return i::Handle<T>::cast(value);
     340             : }
     341             : 
     342       77362 : static inline v8::Local<v8::Value> v8_num(double x) {
     343       77362 :   return v8::Number::New(v8::Isolate::GetCurrent(), x);
     344             : }
     345             : 
     346             : static inline v8::Local<v8::Integer> v8_int(int32_t x) {
     347          40 :   return v8::Integer::New(v8::Isolate::GetCurrent(), x);
     348             : }
     349             : 
     350      502679 : static inline v8::Local<v8::String> v8_str(const char* x) {
     351             :   return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x,
     352      502679 :                                  v8::NewStringType::kNormal)
     353     1005358 :       .ToLocalChecked();
     354             : }
     355             : 
     356             : 
     357         913 : static inline v8::Local<v8::String> v8_str(v8::Isolate* isolate,
     358             :                                            const char* x) {
     359             :   return v8::String::NewFromUtf8(isolate, x, v8::NewStringType::kNormal)
     360        1826 :       .ToLocalChecked();
     361             : }
     362             : 
     363             : 
     364           5 : static inline v8::Local<v8::Symbol> v8_symbol(const char* name) {
     365           5 :   return v8::Symbol::New(v8::Isolate::GetCurrent(), v8_str(name));
     366             : }
     367             : 
     368             : 
     369      116428 : static inline v8::Local<v8::Script> v8_compile(v8::Local<v8::String> x) {
     370             :   v8::Local<v8::Script> result;
     371      232855 :   if (v8::Script::Compile(v8::Isolate::GetCurrent()->GetCurrentContext(), x)
     372      116428 :           .ToLocal(&result)) {
     373      116417 :     return result;
     374             :   }
     375          10 :   return v8::Local<v8::Script>();
     376             : }
     377             : 
     378             : 
     379             : static inline v8::Local<v8::Script> v8_compile(const char* x) {
     380        2224 :   return v8_compile(v8_str(x));
     381             : }
     382             : 
     383             : 
     384        2054 : static inline int32_t v8_run_int32value(v8::Local<v8::Script> script) {
     385        2054 :   v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
     386        6162 :   return script->Run(context).ToLocalChecked()->Int32Value(context).FromJust();
     387             : }
     388             : 
     389             : 
     390          60 : static inline v8::Local<v8::Script> CompileWithOrigin(
     391             :     v8::Local<v8::String> source, v8::Local<v8::String> origin_url) {
     392             :   v8::ScriptOrigin origin(origin_url);
     393             :   v8::ScriptCompiler::Source script_source(source, origin);
     394             :   return v8::ScriptCompiler::Compile(
     395          60 :              v8::Isolate::GetCurrent()->GetCurrentContext(), &script_source)
     396         120 :       .ToLocalChecked();
     397             : }
     398             : 
     399             : 
     400             : static inline v8::Local<v8::Script> CompileWithOrigin(
     401             :     v8::Local<v8::String> source, const char* origin_url) {
     402          17 :   return CompileWithOrigin(source, v8_str(origin_url));
     403             : }
     404             : 
     405             : 
     406          27 : static inline v8::Local<v8::Script> CompileWithOrigin(const char* source,
     407             :                                                       const char* origin_url) {
     408          27 :   return CompileWithOrigin(v8_str(source), v8_str(origin_url));
     409             : }
     410             : 
     411             : 
     412             : // Helper functions that compile and run the source.
     413         273 : static inline v8::MaybeLocal<v8::Value> CompileRun(
     414             :     v8::Local<v8::Context> context, const char* source) {
     415         273 :   return v8::Script::Compile(context, v8_str(source))
     416         273 :       .ToLocalChecked()
     417         273 :       ->Run(context);
     418             : }
     419             : 
     420             : 
     421         538 : static inline v8::Local<v8::Value> CompileRunChecked(v8::Isolate* isolate,
     422             :                                                      const char* source) {
     423             :   v8::Local<v8::String> source_string =
     424             :       v8::String::NewFromUtf8(isolate, source, v8::NewStringType::kNormal)
     425        1076 :           .ToLocalChecked();
     426         538 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     427             :   v8::Local<v8::Script> script =
     428         538 :       v8::Script::Compile(context, source_string).ToLocalChecked();
     429        1076 :   return script->Run(context).ToLocalChecked();
     430             : }
     431             : 
     432             : 
     433      114077 : static inline v8::Local<v8::Value> CompileRun(v8::Local<v8::String> source) {
     434             :   v8::Local<v8::Value> result;
     435      114077 :   if (v8_compile(source)
     436      228154 :           ->Run(v8::Isolate::GetCurrent()->GetCurrentContext())
     437      114076 :           .ToLocal(&result)) {
     438      111516 :     return result;
     439             :   }
     440        2561 :   return v8::Local<v8::Value>();
     441             : }
     442             : 
     443             : 
     444             : // Helper functions that compile and run the source.
     445             : static inline v8::Local<v8::Value> CompileRun(const char* source) {
     446      112234 :   return CompileRun(v8_str(source));
     447             : }
     448             : 
     449             : 
     450          80 : static inline v8::Local<v8::Value> CompileRun(
     451             :     v8::Local<v8::Context> context, v8::ScriptCompiler::Source* script_source,
     452             :     v8::ScriptCompiler::CompileOptions options) {
     453             :   v8::Local<v8::Value> result;
     454          80 :   if (v8::ScriptCompiler::Compile(context, script_source, options)
     455          80 :           .ToLocalChecked()
     456             :           ->Run(context)
     457          80 :           .ToLocal(&result)) {
     458          60 :     return result;
     459             :   }
     460          20 :   return v8::Local<v8::Value>();
     461             : }
     462             : 
     463             : 
     464             : // Helper functions that compile and run the source with given origin.
     465          60 : static inline v8::Local<v8::Value> CompileRunWithOrigin(const char* source,
     466             :                                                         const char* origin_url,
     467             :                                                         int line_number,
     468             :                                                         int column_number) {
     469          60 :   v8::Isolate* isolate = v8::Isolate::GetCurrent();
     470          60 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     471             :   v8::ScriptOrigin origin(v8_str(origin_url),
     472             :                           v8::Integer::New(isolate, line_number),
     473          60 :                           v8::Integer::New(isolate, column_number));
     474          60 :   v8::ScriptCompiler::Source script_source(v8_str(source), origin);
     475             :   return CompileRun(context, &script_source,
     476         120 :                     v8::ScriptCompiler::CompileOptions());
     477             : }
     478             : 
     479             : 
     480          20 : static inline v8::Local<v8::Value> CompileRunWithOrigin(
     481             :     v8::Local<v8::String> source, const char* origin_url) {
     482          20 :   v8::Isolate* isolate = v8::Isolate::GetCurrent();
     483          20 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     484             :   v8::ScriptCompiler::Source script_source(
     485          20 :       source, v8::ScriptOrigin(v8_str(origin_url)));
     486             :   return CompileRun(context, &script_source,
     487          40 :                     v8::ScriptCompiler::CompileOptions());
     488             : }
     489             : 
     490             : 
     491             : static inline v8::Local<v8::Value> CompileRunWithOrigin(
     492             :     const char* source, const char* origin_url) {
     493          20 :   return CompileRunWithOrigin(v8_str(source), origin_url);
     494             : }
     495             : 
     496             : // Takes a JSFunction and runs it through the test version of the optimizing
     497             : // pipeline, allocating the temporary compilation artifacts in a given Zone.
     498             : // For possible {flags} values, look at OptimizedCompilationInfo::Flag.
     499             : // If passed a non-null pointer for {broker}, outputs the JSHeapBroker to it.
     500             : i::Handle<i::JSFunction> Optimize(
     501             :     i::Handle<i::JSFunction> function, i::Zone* zone, i::Isolate* isolate,
     502             :     uint32_t flags, i::compiler::JSHeapBroker** out_broker = nullptr);
     503             : 
     504         872 : static inline void ExpectString(const char* code, const char* expected) {
     505             :   v8::Local<v8::Value> result = CompileRun(code);
     506         872 :   CHECK(result->IsString());
     507         872 :   v8::String::Utf8Value utf8(v8::Isolate::GetCurrent(), result);
     508         872 :   CHECK_EQ(0, strcmp(expected, *utf8));
     509         872 : }
     510             : 
     511             : 
     512        1238 : static inline void ExpectInt32(const char* code, int expected) {
     513             :   v8::Local<v8::Value> result = CompileRun(code);
     514        1238 :   CHECK(result->IsInt32());
     515        2476 :   CHECK_EQ(expected,
     516             :            result->Int32Value(v8::Isolate::GetCurrent()->GetCurrentContext())
     517             :                .FromJust());
     518        1238 : }
     519             : 
     520             : 
     521         882 : static inline void ExpectBoolean(const char* code, bool expected) {
     522             :   v8::Local<v8::Value> result = CompileRun(code);
     523         882 :   CHECK(result->IsBoolean());
     524         882 :   CHECK_EQ(expected, result->BooleanValue(v8::Isolate::GetCurrent()));
     525         882 : }
     526             : 
     527             : 
     528             : static inline void ExpectTrue(const char* code) {
     529         254 :   ExpectBoolean(code, true);
     530             : }
     531             : 
     532             : 
     533             : static inline void ExpectFalse(const char* code) {
     534          89 :   ExpectBoolean(code, false);
     535             : }
     536             : 
     537             : 
     538          92 : static inline void ExpectObject(const char* code,
     539             :                                 v8::Local<v8::Value> expected) {
     540             :   v8::Local<v8::Value> result = CompileRun(code);
     541          92 :   CHECK(result->SameValue(expected));
     542          92 : }
     543             : 
     544             : 
     545          42 : static inline void ExpectUndefined(const char* code) {
     546             :   v8::Local<v8::Value> result = CompileRun(code);
     547          42 :   CHECK(result->IsUndefined());
     548          42 : }
     549             : 
     550             : 
     551             : static inline void ExpectNull(const char* code) {
     552             :   v8::Local<v8::Value> result = CompileRun(code);
     553             :   CHECK(result->IsNull());
     554             : }
     555             : 
     556             : 
     557           5 : static inline void CheckDoubleEquals(double expected, double actual) {
     558             :   const double kEpsilon = 1e-10;
     559          10 :   CHECK_LE(expected, actual + kEpsilon);
     560          10 :   CHECK_GE(expected, actual - kEpsilon);
     561           5 : }
     562             : 
     563     4709250 : static v8::debug::DebugDelegate dummy_delegate;
     564             : 
     565             : static inline void EnableDebugger(v8::Isolate* isolate) {
     566          30 :   v8::debug::SetDebugDelegate(isolate, &dummy_delegate);
     567             : }
     568             : 
     569             : 
     570             : static inline void DisableDebugger(v8::Isolate* isolate) {
     571          25 :   v8::debug::SetDebugDelegate(isolate, nullptr);
     572             : }
     573             : 
     574             : 
     575       25506 : static inline void EmptyMessageQueues(v8::Isolate* isolate) {
     576       68378 :   while (v8::platform::PumpMessageLoop(v8::internal::V8::GetCurrentPlatform(),
     577       42872 :                                        isolate)) {
     578             :   }
     579       25506 : }
     580             : 
     581             : class InitializedHandleScopeImpl;
     582             : 
     583        3844 : class InitializedHandleScope {
     584             :  public:
     585             :   InitializedHandleScope();
     586             :   ~InitializedHandleScope();
     587             : 
     588             :   // Prefixing the below with main_ reduces a lot of naming clashes.
     589             :   i::Isolate* main_isolate() { return main_isolate_; }
     590             : 
     591             :  private:
     592             :   i::Isolate* main_isolate_;
     593             :   std::unique_ptr<InitializedHandleScopeImpl> initialized_handle_scope_impl_;
     594             : };
     595             : 
     596     4326639 : class HandleAndZoneScope : public InitializedHandleScope {
     597             :  public:
     598             :   HandleAndZoneScope();
     599             :   ~HandleAndZoneScope();
     600             : 
     601             :   // Prefixing the below with main_ reduces a lot of naming clashes.
     602             :   i::Zone* main_zone() { return main_zone_.get(); }
     603             : 
     604             :  private:
     605             :   v8::internal::AccountingAllocator allocator_;
     606             :   std::unique_ptr<i::Zone> main_zone_;
     607             : };
     608             : 
     609             : class StaticOneByteResource : public v8::String::ExternalOneByteStringResource {
     610             :  public:
     611           5 :   explicit StaticOneByteResource(const char* data) : data_(data) {}
     612             : 
     613          10 :   ~StaticOneByteResource() override = default;
     614             : 
     615          10 :   const char* data() const override { return data_; }
     616             : 
     617          20 :   size_t length() const override { return strlen(data_); }
     618             : 
     619             :  private:
     620             :   const char* data_;
     621             : };
     622             : 
     623             : class ManualGCScope {
     624             :  public:
     625             :   ManualGCScope()
     626             :       : flag_concurrent_marking_(i::FLAG_concurrent_marking),
     627             :         flag_concurrent_sweeping_(i::FLAG_concurrent_sweeping),
     628             :         flag_stress_incremental_marking_(i::FLAG_stress_incremental_marking),
     629             :         flag_parallel_marking_(i::FLAG_parallel_marking),
     630             :         flag_detect_ineffective_gcs_near_heap_limit_(
     631         502 :             i::FLAG_detect_ineffective_gcs_near_heap_limit) {
     632         502 :     i::FLAG_concurrent_marking = false;
     633         502 :     i::FLAG_concurrent_sweeping = false;
     634         502 :     i::FLAG_stress_incremental_marking = false;
     635             :     // Parallel marking has a dependency on concurrent marking.
     636         502 :     i::FLAG_parallel_marking = false;
     637         502 :     i::FLAG_detect_ineffective_gcs_near_heap_limit = false;
     638             :   }
     639             :   ~ManualGCScope() {
     640         502 :     i::FLAG_concurrent_marking = flag_concurrent_marking_;
     641         502 :     i::FLAG_concurrent_sweeping = flag_concurrent_sweeping_;
     642         502 :     i::FLAG_stress_incremental_marking = flag_stress_incremental_marking_;
     643         502 :     i::FLAG_parallel_marking = flag_parallel_marking_;
     644             :     i::FLAG_detect_ineffective_gcs_near_heap_limit =
     645         502 :         flag_detect_ineffective_gcs_near_heap_limit_;
     646             :   }
     647             : 
     648             :  private:
     649             :   bool flag_concurrent_marking_;
     650             :   bool flag_concurrent_sweeping_;
     651             :   bool flag_stress_incremental_marking_;
     652             :   bool flag_parallel_marking_;
     653             :   bool flag_detect_ineffective_gcs_near_heap_limit_;
     654             : };
     655             : 
     656             : // This is an abstract base class that can be overridden to implement a test
     657             : // platform. It delegates all operations to a given platform at the time
     658             : // of construction.
     659             : class TestPlatform : public v8::Platform {
     660             :  public:
     661             :   // v8::Platform implementation.
     662           0 :   v8::PageAllocator* GetPageAllocator() override {
     663           0 :     return old_platform_->GetPageAllocator();
     664             :   }
     665             : 
     666           0 :   void OnCriticalMemoryPressure() override {
     667           0 :     old_platform_->OnCriticalMemoryPressure();
     668           0 :   }
     669             : 
     670           0 :   bool OnCriticalMemoryPressure(size_t length) override {
     671           0 :     return old_platform_->OnCriticalMemoryPressure(length);
     672             :   }
     673             : 
     674         181 :   int NumberOfWorkerThreads() override {
     675         181 :     return old_platform_->NumberOfWorkerThreads();
     676             :   }
     677             : 
     678           6 :   std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
     679             :       v8::Isolate* isolate) override {
     680           6 :     return old_platform_->GetForegroundTaskRunner(isolate);
     681             :   }
     682             : 
     683           7 :   void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override {
     684          21 :     old_platform_->CallOnWorkerThread(std::move(task));
     685           7 :   }
     686             : 
     687           0 :   void CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task,
     688             :                                  double delay_in_seconds) override {
     689           0 :     old_platform_->CallDelayedOnWorkerThread(std::move(task), delay_in_seconds);
     690           0 :   }
     691             : 
     692           0 :   void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override {
     693             :     // This is a deprecated function and should not be called anymore.
     694           0 :     UNREACHABLE();
     695             :   }
     696             : 
     697           0 :   void CallDelayedOnForegroundThread(v8::Isolate* isolate, v8::Task* task,
     698             :                                      double delay_in_seconds) override {
     699             :     // This is a deprecated function and should not be called anymore.
     700           0 :     UNREACHABLE();
     701             :   }
     702             : 
     703       17693 :   double MonotonicallyIncreasingTime() override {
     704       17693 :     return old_platform_->MonotonicallyIncreasingTime();
     705             :   }
     706             : 
     707           0 :   double CurrentClockTimeMillis() override {
     708           0 :     return old_platform_->CurrentClockTimeMillis();
     709             :   }
     710             : 
     711           0 :   void CallIdleOnForegroundThread(v8::Isolate* isolate,
     712             :                                   v8::IdleTask* task) override {
     713             :     // This is a deprecated function and should not be called anymore.
     714           0 :     UNREACHABLE();
     715             :   }
     716             : 
     717           0 :   bool IdleTasksEnabled(v8::Isolate* isolate) override {
     718           0 :     return old_platform_->IdleTasksEnabled(isolate);
     719             :   }
     720             : 
     721        3569 :   v8::TracingController* GetTracingController() override {
     722        3569 :     return old_platform_->GetTracingController();
     723             :   }
     724             : 
     725             :  protected:
     726         240 :   TestPlatform() : old_platform_(i::V8::GetCurrentPlatform()) {}
     727         225 :   ~TestPlatform() override { i::V8::SetPlatformForTesting(old_platform_); }
     728             : 
     729             :   v8::Platform* old_platform() const { return old_platform_; }
     730             : 
     731             :  private:
     732             :   v8::Platform* old_platform_;
     733             : 
     734             :   DISALLOW_COPY_AND_ASSIGN(TestPlatform);
     735             : };
     736             : 
     737             : #endif  // ifndef CCTEST_H_

Generated by: LCOV version 1.10