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