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/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 22202080 : : data_(data), length_(length) {}
70 :
71 2128182 : 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 2128182 : 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 4256364 : rhs->length_) == 0;
80 : }
81 :
82 : uint32_t Hash() {
83 : return StringHasher::HashSequentialString<uint8_t>(
84 22202080 : data_, length_, v8::internal::kZeroHashSeed);
85 : }
86 :
87 : const unsigned char* data_;
88 : const int length_;
89 : };
90 :
91 17366 : void InitializeIntrinsicFunctionNames() {
92 : base::CustomMatcherHashMap* function_name_map =
93 17366 : new base::CustomMatcherHashMap(IntrinsicFunctionIdentifier::Match);
94 19988266 : for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
95 19970900 : const Runtime::Function* function = &kIntrinsicFunctions[i];
96 : IntrinsicFunctionIdentifier* identifier = new IntrinsicFunctionIdentifier(
97 : reinterpret_cast<const unsigned char*>(function->name),
98 19970900 : static_cast<int>(strlen(function->name)));
99 : base::HashMap::Entry* entry =
100 19970900 : function_name_map->InsertNew(identifier, identifier->Hash());
101 19970900 : entry->value = const_cast<Runtime::Function*>(function);
102 : }
103 17366 : kRuntimeFunctionNameMap = function_name_map;
104 17366 : }
105 :
106 : } // namespace
107 :
108 2231180 : const Runtime::Function* Runtime::FunctionForName(const unsigned char* name,
109 : int length) {
110 : base::CallOnce(&initialize_function_name_map_once,
111 2231180 : &InitializeIntrinsicFunctionNames);
112 : IntrinsicFunctionIdentifier identifier(name, length);
113 : base::HashMap::Entry* entry =
114 4462360 : kRuntimeFunctionNameMap->Lookup(&identifier, identifier.Hash());
115 2231180 : if (entry) {
116 1989254 : return reinterpret_cast<Function*>(entry->value);
117 : }
118 : return NULL;
119 : }
120 :
121 :
122 0 : const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
123 0 : for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
124 0 : if (entry == kIntrinsicFunctions[i].entry) {
125 0 : return &(kIntrinsicFunctions[i]);
126 : }
127 : }
128 : return NULL;
129 : }
130 :
131 :
132 43500627 : const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
133 43500627 : return &(kIntrinsicFunctions[static_cast<int>(id)]);
134 : }
135 :
136 :
137 61314 : const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) {
138 61314 : 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 0 : if (!isolate->runtime_state()->redirected_intrinsic_functions()) {
142 : size_t function_count = arraysize(kIntrinsicFunctions);
143 0 : Function* redirected_functions = new Function[function_count];
144 : memcpy(redirected_functions, kIntrinsicFunctions,
145 : sizeof(kIntrinsicFunctions));
146 0 : for (size_t i = 0; i < function_count; i++) {
147 : ExternalReference redirected_entry(static_cast<Runtime::FunctionId>(i),
148 0 : isolate);
149 0 : redirected_functions[i].entry = redirected_entry.address();
150 : }
151 : isolate->runtime_state()->set_redirected_intrinsic_functions(
152 : redirected_functions);
153 : }
154 :
155 0 : return isolate->runtime_state()->redirected_intrinsic_functions();
156 : } else {
157 : return kIntrinsicFunctions;
158 : }
159 : }
160 :
161 :
162 0 : std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
163 0 : return os << Runtime::FunctionForId(id)->name;
164 : }
165 :
166 :
167 : } // namespace internal
168 : } // namespace v8
|