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