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/assembler.h" 8#include "src/base/hashmap.h" 9#include "src/contexts.h" 10#include "src/handles-inl.h" 11#include "src/heap/heap.h" 12#include "src/isolate.h" 13#include "src/runtime/runtime-utils.h" 14 15namespace v8 { 16namespace internal { 17 18// Header of runtime functions. 19#define F(name, number_of_args, result_size) \ 20 Object* Runtime_##name(int args_length, Object** args_object, \ 21 Isolate* isolate); 22FOR_EACH_INTRINSIC_RETURN_OBJECT(F) 23#undef F 24 25#define P(name, number_of_args, result_size) \ 26 ObjectPair Runtime_##name(int args_length, Object** args_object, \ 27 Isolate* isolate); 28FOR_EACH_INTRINSIC_RETURN_PAIR(P) 29#undef P 30 31#define T(name, number_of_args, result_size) \ 32 ObjectTriple Runtime_##name(int args_length, Object** args_object, \ 33 Isolate* isolate); 34FOR_EACH_INTRINSIC_RETURN_TRIPLE(T) 35#undef T 36 37 38#define F(name, number_of_args, result_size) \ 39 { \ 40 Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \ 41 number_of_args, result_size \ 42 } \ 43 , 44 45 46#define I(name, number_of_args, result_size) \ 47 { \ 48 Runtime::kInline##name, Runtime::INLINE, "_" #name, \ 49 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \ 50 } \ 51 , 52 53static const Runtime::Function kIntrinsicFunctions[] = { 54 FOR_EACH_INTRINSIC(F) 55 FOR_EACH_INTRINSIC(I) 56}; 57 58#undef I 59#undef F 60 61namespace { 62 63V8_DECLARE_ONCE(initialize_function_name_map_once); 64static const base::CustomMatcherHashMap* kRuntimeFunctionNameMap; 65 66struct IntrinsicFunctionIdentifier { 67 IntrinsicFunctionIdentifier(const unsigned char* data, const int length) 68 : data_(data), length_(length) {} 69 70 static bool Match(void* key1, void* key2) { 71 const IntrinsicFunctionIdentifier* lhs = 72 static_cast<IntrinsicFunctionIdentifier*>(key1); 73 const IntrinsicFunctionIdentifier* rhs = 74 static_cast<IntrinsicFunctionIdentifier*>(key2); 75 if (lhs->length_ != rhs->length_) return false; 76 return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs->data_), 77 reinterpret_cast<const uint8_t*>(rhs->data_), 78 rhs->length_) == 0; 79 } 80 81 uint32_t Hash() { 82 return StringHasher::HashSequentialString<uint8_t>( 83 data_, length_, v8::internal::kZeroHashSeed); 84 } 85 86 const unsigned char* data_; 87 const int length_; 88}; 89 90void InitializeIntrinsicFunctionNames() { 91 base::CustomMatcherHashMap* function_name_map = 92 new base::CustomMatcherHashMap(IntrinsicFunctionIdentifier::Match); 93 for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) { 94 const Runtime::Function* function = &kIntrinsicFunctions[i]; 95 IntrinsicFunctionIdentifier* identifier = new IntrinsicFunctionIdentifier( 96 reinterpret_cast<const unsigned char*>(function->name), 97 static_cast<int>(strlen(function->name))); 98 base::HashMap::Entry* entry = 99 function_name_map->InsertNew(identifier, identifier->Hash()); 100 entry->value = const_cast<Runtime::Function*>(function); 101 } 102 kRuntimeFunctionNameMap = function_name_map; 103} 104 105} // namespace 106 107const Runtime::Function* Runtime::FunctionForName(const unsigned char* name, 108 int length) { 109 base::CallOnce(&initialize_function_name_map_once, 110 &InitializeIntrinsicFunctionNames); 111 IntrinsicFunctionIdentifier identifier(name, length); 112 base::HashMap::Entry* entry = 113 kRuntimeFunctionNameMap->Lookup(&identifier, identifier.Hash()); 114 if (entry) { 115 return reinterpret_cast<Function*>(entry->value); 116 } 117 return NULL; 118} 119 120 121const Runtime::Function* Runtime::FunctionForEntry(Address entry) { 122 for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) { 123 if (entry == kIntrinsicFunctions[i].entry) { 124 return &(kIntrinsicFunctions[i]); 125 } 126 } 127 return NULL; 128} 129 130 131const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 132 return &(kIntrinsicFunctions[static_cast<int>(id)]); 133} 134 135 136const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) { 137 if (isolate->external_reference_redirector()) { 138 // When running with the simulator we need to provide a table which has 139 // redirected runtime entry addresses. 140 if (!isolate->runtime_state()->redirected_intrinsic_functions()) { 141 size_t function_count = arraysize(kIntrinsicFunctions); 142 Function* redirected_functions = new Function[function_count]; 143 memcpy(redirected_functions, kIntrinsicFunctions, 144 sizeof(kIntrinsicFunctions)); 145 for (size_t i = 0; i < function_count; i++) { 146 ExternalReference redirected_entry(static_cast<Runtime::FunctionId>(i), 147 isolate); 148 redirected_functions[i].entry = redirected_entry.address(); 149 } 150 isolate->runtime_state()->set_redirected_intrinsic_functions( 151 redirected_functions); 152 } 153 154 return isolate->runtime_state()->redirected_intrinsic_functions(); 155 } else { 156 return kIntrinsicFunctions; 157 } 158} 159 160 161std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) { 162 return os << Runtime::FunctionForId(id)->name; 163} 164 165 166} // namespace internal 167} // namespace v8 168