LCOV - code coverage report
Current view: top level - src/runtime - runtime.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 37 39 94.9 %
Date: 2019-04-17 Functions: 9 10 90.0 %

          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     5682316 :       : data_(data), length_(length) {}
      61             : 
      62      146991 :   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      146991 :     if (lhs->length_ != rhs->length_) return false;
      68      293990 :     return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs->data_),
      69      146995 :                                 reinterpret_cast<const uint8_t*>(rhs->data_),
      70      146995 :                                 rhs->length_) == 0;
      71             :   }
      72             : 
      73             :   uint32_t Hash() {
      74             :     return StringHasher::HashSequentialString<uint8_t>(
      75     5682316 :         data_, length_, v8::internal::kZeroHashSeed);
      76             :   }
      77             : 
      78             :   const unsigned char* data_;
      79             :   const int length_;
      80             : };
      81             : 
      82       11484 : void InitializeIntrinsicFunctionNames() {
      83             :   base::CustomMatcherHashMap* function_name_map =
      84       11484 :       new base::CustomMatcherHashMap(IntrinsicFunctionIdentifier::Match);
      85    11242836 :   for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
      86     5615676 :     const Runtime::Function* function = &kIntrinsicFunctions[i];
      87             :     IntrinsicFunctionIdentifier* identifier = new IntrinsicFunctionIdentifier(
      88             :         reinterpret_cast<const unsigned char*>(function->name),
      89     5615676 :         static_cast<int>(strlen(function->name)));
      90             :     base::HashMap::Entry* entry =
      91     5615676 :         function_name_map->InsertNew(identifier, identifier->Hash());
      92     5615676 :     entry->value = const_cast<Runtime::Function*>(function);
      93             :   }
      94       11484 :   kRuntimeFunctionNameMap = function_name_map;
      95       11484 : }
      96             : 
      97             : }  // namespace
      98             : 
      99      379013 : bool Runtime::NeedsExactContext(FunctionId id) {
     100      379013 :   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::kThrowAccessedUninitializedVariable:
     128             :     case Runtime::kThrowStackOverflow:
     129             :     case Runtime::kThrowStaticPrototypeError:
     130             :     case Runtime::kThrowSuperAlreadyCalledError:
     131             :     case Runtime::kThrowSuperNotCalled:
     132             :     case Runtime::kThrowSymbolAsyncIteratorInvalid:
     133             :     case Runtime::kThrowSymbolIteratorInvalid:
     134             :     case Runtime::kThrowThrowMethodMissing:
     135             :     case Runtime::kThrowTypeError:
     136             :     case Runtime::kThrowUnsupportedSuperError:
     137             :     case Runtime::kThrowWasmError:
     138             :     case Runtime::kThrowWasmStackOverflow:
     139             :       return false;
     140             :     default:
     141      227375 :       return true;
     142             :   }
     143             : }
     144             : 
     145      165534 : bool Runtime::IsNonReturning(FunctionId id) {
     146      165534 :   switch (id) {
     147             :     case Runtime::kThrowUnsupportedSuperError:
     148             :     case Runtime::kThrowConstructorNonCallableError:
     149             :     case Runtime::kThrowStaticPrototypeError:
     150             :     case Runtime::kThrowSuperAlreadyCalledError:
     151             :     case Runtime::kThrowSuperNotCalled:
     152             :     case Runtime::kReThrow:
     153             :     case Runtime::kThrow:
     154             :     case Runtime::kThrowApplyNonFunction:
     155             :     case Runtime::kThrowCalledNonCallable:
     156             :     case Runtime::kThrowConstructedNonConstructable:
     157             :     case Runtime::kThrowConstructorReturnedNonObject:
     158             :     case Runtime::kThrowInvalidStringLength:
     159             :     case Runtime::kThrowInvalidTypedArrayAlignment:
     160             :     case Runtime::kThrowIteratorError:
     161             :     case Runtime::kThrowIteratorResultNotAnObject:
     162             :     case Runtime::kThrowThrowMethodMissing:
     163             :     case Runtime::kThrowSymbolIteratorInvalid:
     164             :     case Runtime::kThrowNotConstructor:
     165             :     case Runtime::kThrowRangeError:
     166             :     case Runtime::kThrowReferenceError:
     167             :     case Runtime::kThrowAccessedUninitializedVariable:
     168             :     case Runtime::kThrowStackOverflow:
     169             :     case Runtime::kThrowSymbolAsyncIteratorInvalid:
     170             :     case Runtime::kThrowTypeError:
     171             :     case Runtime::kThrowConstAssignError:
     172             :     case Runtime::kThrowWasmError:
     173             :     case Runtime::kThrowWasmStackOverflow:
     174             :       return true;
     175             :     default:
     176      140752 :       return false;
     177             :   }
     178             : }
     179             : 
     180       66651 : const Runtime::Function* Runtime::FunctionForName(const unsigned char* name,
     181             :                                                   int length) {
     182       66640 :   base::CallOnce(&initialize_function_name_map_once,
     183       66651 :                  &InitializeIntrinsicFunctionNames);
     184             :   IntrinsicFunctionIdentifier identifier(name, length);
     185             :   base::HashMap::Entry* entry =
     186      133285 :       kRuntimeFunctionNameMap->Lookup(&identifier, identifier.Hash());
     187       66652 :   if (entry) {
     188       66607 :     return reinterpret_cast<Function*>(entry->value);
     189             :   }
     190             :   return nullptr;
     191             : }
     192             : 
     193             : 
     194          64 : const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
     195       41920 :   for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
     196       20960 :     if (entry == kIntrinsicFunctions[i].entry) {
     197          32 :       return &(kIntrinsicFunctions[i]);
     198             :     }
     199             :   }
     200             :   return nullptr;
     201             : }
     202             : 
     203             : 
     204    33795914 : const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
     205    33795914 :   return &(kIntrinsicFunctions[static_cast<int>(id)]);
     206             : }
     207             : 
     208       62774 : const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) {
     209             : #ifdef USE_SIMULATOR
     210             :   // When running with the simulator we need to provide a table which has
     211             :   // redirected runtime entry addresses.
     212             :   if (!isolate->runtime_state()->redirected_intrinsic_functions()) {
     213             :     size_t function_count = arraysize(kIntrinsicFunctions);
     214             :     Function* redirected_functions = new Function[function_count];
     215             :     memcpy(redirected_functions, kIntrinsicFunctions,
     216             :            sizeof(kIntrinsicFunctions));
     217             :     for (size_t i = 0; i < function_count; i++) {
     218             :       ExternalReference redirected_entry =
     219             :           ExternalReference::Create(static_cast<Runtime::FunctionId>(i));
     220             :       redirected_functions[i].entry = redirected_entry.address();
     221             :     }
     222             :     isolate->runtime_state()->set_redirected_intrinsic_functions(
     223             :         redirected_functions);
     224             :   }
     225             : 
     226             :   return isolate->runtime_state()->redirected_intrinsic_functions();
     227             : #else
     228       62774 :   return kIntrinsicFunctions;
     229             : #endif
     230             : }
     231             : 
     232           0 : std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
     233           0 :   return os << Runtime::FunctionForId(id)->name;
     234             : }
     235             : 
     236             : 
     237             : }  // namespace internal
     238      122004 : }  // namespace v8

Generated by: LCOV version 1.10