LCOV - code coverage report
Current view: top level - src/runtime - runtime.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 34 36 94.4 %
Date: 2019-01-20 Functions: 10 11 90.9 %

          Line data    Source code
       1             : // Copyright 2012 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 "src/runtime/runtime.h"
       6             : 
       7             : #include "src/base/hashmap.h"
       8             : #include "src/contexts.h"
       9             : #include "src/handles-inl.h"
      10             : #include "src/heap/heap.h"
      11             : #include "src/isolate.h"
      12             : #include "src/objects-inl.h"
      13             : #include "src/reloc-info.h"
      14             : #include "src/runtime/runtime-utils.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : // Header of runtime functions.
      20             : #define F(name, number_of_args, result_size)                    \
      21             :   Address Runtime_##name(int args_length, Address* args_object, \
      22             :                          Isolate* isolate);
      23             : FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
      24             : #undef F
      25             : 
      26             : #define P(name, number_of_args, result_size)                       \
      27             :   ObjectPair Runtime_##name(int args_length, Address* args_object, \
      28             :                             Isolate* isolate);
      29             : FOR_EACH_INTRINSIC_RETURN_PAIR(P)
      30             : #undef P
      31             : 
      32             : #define F(name, number_of_args, result_size)                                  \
      33             :   {                                                                           \
      34             :     Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
      35             :         number_of_args, result_size                                           \
      36             :   }                                                                           \
      37             :   ,
      38             : 
      39             : 
      40             : #define I(name, number_of_args, result_size)                       \
      41             :   {                                                                \
      42             :     Runtime::kInline##name, Runtime::INLINE, "_" #name,            \
      43             :         FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \
      44             :   }                                                                \
      45             :   ,
      46             : 
      47             : static const Runtime::Function kIntrinsicFunctions[] = {
      48             :     FOR_EACH_INTRINSIC(F) FOR_EACH_INLINE_INTRINSIC(I)};
      49             : 
      50             : #undef I
      51             : #undef F
      52             : 
      53             : namespace {
      54             : 
      55             : V8_DECLARE_ONCE(initialize_function_name_map_once);
      56             : static const base::CustomMatcherHashMap* kRuntimeFunctionNameMap;
      57             : 
      58             : struct IntrinsicFunctionIdentifier {
      59             :   IntrinsicFunctionIdentifier(const unsigned char* data, const int length)
      60     5476876 :       : data_(data), length_(length) {}
      61             : 
      62      133258 :   static bool Match(void* key1, void* key2) {
      63             :     const IntrinsicFunctionIdentifier* lhs =
      64             :         static_cast<IntrinsicFunctionIdentifier*>(key1);
      65             :     const IntrinsicFunctionIdentifier* rhs =
      66             :         static_cast<IntrinsicFunctionIdentifier*>(key2);
      67      133258 :     if (lhs->length_ != rhs->length_) return false;
      68             :     return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs->data_),
      69             :                                 reinterpret_cast<const uint8_t*>(rhs->data_),
      70      266518 :                                 rhs->length_) == 0;
      71             :   }
      72             : 
      73             :   uint32_t Hash() {
      74             :     return StringHasher::HashSequentialString<uint8_t>(
      75     5476876 :         data_, length_, v8::internal::kZeroHashSeed);
      76             :   }
      77             : 
      78             :   const unsigned char* data_;
      79             :   const int length_;
      80             : };
      81             : 
      82       11226 : void InitializeIntrinsicFunctionNames() {
      83             :   base::CustomMatcherHashMap* function_name_map =
      84       11226 :       new base::CustomMatcherHashMap(IntrinsicFunctionIdentifier::Match);
      85     5433384 :   for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
      86     5422158 :     const Runtime::Function* function = &kIntrinsicFunctions[i];
      87             :     IntrinsicFunctionIdentifier* identifier = new IntrinsicFunctionIdentifier(
      88             :         reinterpret_cast<const unsigned char*>(function->name),
      89     5422158 :         static_cast<int>(strlen(function->name)));
      90             :     base::HashMap::Entry* entry =
      91     5422158 :         function_name_map->InsertNew(identifier, identifier->Hash());
      92     5422158 :     entry->value = const_cast<Runtime::Function*>(function);
      93             :   }
      94       11226 :   kRuntimeFunctionNameMap = function_name_map;
      95       11226 : }
      96             : 
      97             : }  // namespace
      98             : 
      99      356797 : bool Runtime::NeedsExactContext(FunctionId id) {
     100      356797 :   switch (id) {
     101             :     case Runtime::kInlineAsyncFunctionReject:
     102             :     case Runtime::kInlineAsyncFunctionResolve:
     103             :       // For %_AsyncFunctionReject and %_AsyncFunctionResolve we don't
     104             :       // really need the current context, which in particular allows
     105             :       // us to usually eliminate the catch context for the implicit
     106             :       // try-catch in async function.
     107             :       return false;
     108             :     case Runtime::kAddPrivateField:
     109             :     case Runtime::kCopyDataProperties:
     110             :     case Runtime::kCreateDataProperty:
     111             :     case Runtime::kCreatePrivateNameSymbol:
     112             :     case Runtime::kReThrow:
     113             :     case Runtime::kThrow:
     114             :     case Runtime::kThrowApplyNonFunction:
     115             :     case Runtime::kThrowCalledNonCallable:
     116             :     case Runtime::kThrowConstAssignError:
     117             :     case Runtime::kThrowConstructorNonCallableError:
     118             :     case Runtime::kThrowConstructedNonConstructable:
     119             :     case Runtime::kThrowConstructorReturnedNonObject:
     120             :     case Runtime::kThrowInvalidStringLength:
     121             :     case Runtime::kThrowInvalidTypedArrayAlignment:
     122             :     case Runtime::kThrowIteratorError:
     123             :     case Runtime::kThrowIteratorResultNotAnObject:
     124             :     case Runtime::kThrowNotConstructor:
     125             :     case Runtime::kThrowRangeError:
     126             :     case Runtime::kThrowReferenceError:
     127             :     case Runtime::kThrowStackOverflow:
     128             :     case Runtime::kThrowStaticPrototypeError:
     129             :     case Runtime::kThrowSuperAlreadyCalledError:
     130             :     case Runtime::kThrowSuperNotCalled:
     131             :     case Runtime::kThrowSymbolAsyncIteratorInvalid:
     132             :     case Runtime::kThrowSymbolIteratorInvalid:
     133             :     case Runtime::kThrowThrowMethodMissing:
     134             :     case Runtime::kThrowTypeError:
     135             :     case Runtime::kThrowUnsupportedSuperError:
     136             :     case Runtime::kThrowWasmError:
     137             :     case Runtime::kThrowWasmStackOverflow:
     138             :       return false;
     139             :     default:
     140      220209 :       return true;
     141             :   }
     142             : }
     143             : 
     144      154135 : bool Runtime::IsNonReturning(FunctionId id) {
     145      154135 :   switch (id) {
     146             :     case Runtime::kThrowUnsupportedSuperError:
     147             :     case Runtime::kThrowConstructorNonCallableError:
     148             :     case Runtime::kThrowStaticPrototypeError:
     149             :     case Runtime::kThrowSuperAlreadyCalledError:
     150             :     case Runtime::kThrowSuperNotCalled:
     151             :     case Runtime::kReThrow:
     152             :     case Runtime::kThrow:
     153             :     case Runtime::kThrowApplyNonFunction:
     154             :     case Runtime::kThrowCalledNonCallable:
     155             :     case Runtime::kThrowConstructedNonConstructable:
     156             :     case Runtime::kThrowConstructorReturnedNonObject:
     157             :     case Runtime::kThrowInvalidStringLength:
     158             :     case Runtime::kThrowInvalidTypedArrayAlignment:
     159             :     case Runtime::kThrowIteratorError:
     160             :     case Runtime::kThrowIteratorResultNotAnObject:
     161             :     case Runtime::kThrowThrowMethodMissing:
     162             :     case Runtime::kThrowSymbolIteratorInvalid:
     163             :     case Runtime::kThrowNotConstructor:
     164             :     case Runtime::kThrowRangeError:
     165             :     case Runtime::kThrowReferenceError:
     166             :     case Runtime::kThrowStackOverflow:
     167             :     case Runtime::kThrowSymbolAsyncIteratorInvalid:
     168             :     case Runtime::kThrowTypeError:
     169             :     case Runtime::kThrowConstAssignError:
     170             :     case Runtime::kThrowWasmError:
     171             :     case Runtime::kThrowWasmStackOverflow:
     172             :       return true;
     173             :     default:
     174      129667 :       return false;
     175             :   }
     176             : }
     177             : 
     178       54640 : const Runtime::Function* Runtime::FunctionForName(const unsigned char* name,
     179             :                                                   int length) {
     180             :   base::CallOnce(&initialize_function_name_map_once,
     181       54640 :                  &InitializeIntrinsicFunctionNames);
     182             :   IntrinsicFunctionIdentifier identifier(name, length);
     183             :   base::HashMap::Entry* entry =
     184      109429 :       kRuntimeFunctionNameMap->Lookup(&identifier, identifier.Hash());
     185       54729 :   if (entry) {
     186       54651 :     return reinterpret_cast<Function*>(entry->value);
     187             :   }
     188             :   return nullptr;
     189             : }
     190             : 
     191             : 
     192          58 : const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
     193       18879 :   for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
     194       18850 :     if (entry == kIntrinsicFunctions[i].entry) {
     195          29 :       return &(kIntrinsicFunctions[i]);
     196             :     }
     197             :   }
     198             :   return nullptr;
     199             : }
     200             : 
     201             : 
     202    32408517 : const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
     203    32408517 :   return &(kIntrinsicFunctions[static_cast<int>(id)]);
     204             : }
     205             : 
     206       63230 : const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) {
     207             : #ifdef USE_SIMULATOR
     208             :   // When running with the simulator we need to provide a table which has
     209             :   // redirected runtime entry addresses.
     210             :   if (!isolate->runtime_state()->redirected_intrinsic_functions()) {
     211             :     size_t function_count = arraysize(kIntrinsicFunctions);
     212             :     Function* redirected_functions = new Function[function_count];
     213             :     memcpy(redirected_functions, kIntrinsicFunctions,
     214             :            sizeof(kIntrinsicFunctions));
     215             :     for (size_t i = 0; i < function_count; i++) {
     216             :       ExternalReference redirected_entry =
     217             :           ExternalReference::Create(static_cast<Runtime::FunctionId>(i));
     218             :       redirected_functions[i].entry = redirected_entry.address();
     219             :     }
     220             :     isolate->runtime_state()->set_redirected_intrinsic_functions(
     221             :         redirected_functions);
     222             :   }
     223             : 
     224             :   return isolate->runtime_state()->redirected_intrinsic_functions();
     225             : #else
     226       63230 :   return kIntrinsicFunctions;
     227             : #endif
     228             : }
     229             : 
     230           0 : std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
     231           0 :   return os << Runtime::FunctionForId(id)->name;
     232             : }
     233             : 
     234             : 
     235             : }  // namespace internal
     236      183867 : }  // namespace v8

Generated by: LCOV version 1.10