• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
IntrinsicFunctionIdentifierv8::internal::__anon9d5c120d0111::IntrinsicFunctionIdentifier68   IntrinsicFunctionIdentifier(const unsigned char* data, const int length)
69       : data_(data), length_(length) {}
70 
Matchv8::internal::__anon9d5c120d0111::IntrinsicFunctionIdentifier71   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 
Hashv8::internal::__anon9d5c120d0111::IntrinsicFunctionIdentifier82   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 
InitializeIntrinsicFunctionNames()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 
FunctionForName(const unsigned char * name,int length)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 
FunctionForEntry(Address entry)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 
FunctionForId(Runtime::FunctionId id)132 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
133   return &(kIntrinsicFunctions[static_cast<int>(id)]);
134 }
135 
136 
RuntimeFunctionTable(Isolate * isolate)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 
operator <<(std::ostream & os,Runtime::FunctionId id)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