• 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/runtime/runtime-utils.h"
14 
15 namespace v8 {
16 namespace 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);
22 FOR_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);
28 FOR_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);
34 FOR_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 
53 static const Runtime::Function kIntrinsicFunctions[] = {
54   FOR_EACH_INTRINSIC(F)
55   FOR_EACH_INTRINSIC(I)
56 };
57 
58 #undef I
59 #undef F
60 
61 namespace {
62 
63 V8_DECLARE_ONCE(initialize_function_name_map_once);
64 static const base::CustomMatcherHashMap* kRuntimeFunctionNameMap;
65 
66 struct IntrinsicFunctionIdentifier {
IntrinsicFunctionIdentifierv8::internal::__anonff20b14f0111::IntrinsicFunctionIdentifier67   IntrinsicFunctionIdentifier(const unsigned char* data, const int length)
68       : data_(data), length_(length) {}
69 
Matchv8::internal::__anonff20b14f0111::IntrinsicFunctionIdentifier70   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 
Hashv8::internal::__anonff20b14f0111::IntrinsicFunctionIdentifier81   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 
InitializeIntrinsicFunctionNames()90 void 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 
FunctionForName(const unsigned char * name,int length)107 const 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 
FunctionForEntry(Address entry)121 const 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 
FunctionForId(Runtime::FunctionId id)131 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
132   return &(kIntrinsicFunctions[static_cast<int>(id)]);
133 }
134 
135 
RuntimeFunctionTable(Isolate * isolate)136 const 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 
operator <<(std::ostream & os,Runtime::FunctionId id)161 std::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