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/contexts.h"
9 #include "src/handles-inl.h"
10 #include "src/heap/heap.h"
11 #include "src/isolate.h"
12 #include "src/runtime/runtime-utils.h"
13
14 namespace v8 {
15 namespace internal {
16
17 // Header of runtime functions.
18 #define F(name, number_of_args, result_size) \
19 Object* Runtime_##name(int args_length, Object** args_object, \
20 Isolate* isolate);
21 FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
22 #undef F
23
24 #define P(name, number_of_args, result_size) \
25 ObjectPair Runtime_##name(int args_length, Object** args_object, \
26 Isolate* isolate);
27 FOR_EACH_INTRINSIC_RETURN_PAIR(P)
28 #undef P
29
30 #define T(name, number_of_args, result_size) \
31 ObjectTriple Runtime_##name(int args_length, Object** args_object, \
32 Isolate* isolate);
33 FOR_EACH_INTRINSIC_RETURN_TRIPLE(T)
34 #undef T
35
36
37 #define F(name, number_of_args, result_size) \
38 { \
39 Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
40 number_of_args, result_size \
41 } \
42 ,
43
44
45 #define I(name, number_of_args, result_size) \
46 { \
47 Runtime::kInline##name, Runtime::INLINE, "_" #name, \
48 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \
49 } \
50 ,
51
52 static const Runtime::Function kIntrinsicFunctions[] = {
53 FOR_EACH_INTRINSIC(F)
54 FOR_EACH_INTRINSIC(I)
55 };
56
57 #undef I
58 #undef F
59
60
InitializeIntrinsicFunctionNames(Isolate * isolate,Handle<NameDictionary> dict)61 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
62 Handle<NameDictionary> dict) {
63 DCHECK(dict->NumberOfElements() == 0);
64 HandleScope scope(isolate);
65 for (int i = 0; i < kNumFunctions; ++i) {
66 const char* name = kIntrinsicFunctions[i].name;
67 if (name == NULL) continue;
68 Handle<NameDictionary> new_dict = NameDictionary::Add(
69 dict, isolate->factory()->InternalizeUtf8String(name),
70 Handle<Smi>(Smi::FromInt(i), isolate), PropertyDetails::Empty());
71 // The dictionary does not need to grow.
72 CHECK(new_dict.is_identical_to(dict));
73 }
74 }
75
76
FunctionForName(Handle<String> name)77 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
78 Heap* heap = name->GetHeap();
79 int entry = heap->intrinsic_function_names()->FindEntry(name);
80 if (entry != kNotFound) {
81 Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
82 int function_index = Smi::cast(smi_index)->value();
83 return &(kIntrinsicFunctions[function_index]);
84 }
85 return NULL;
86 }
87
88
FunctionForEntry(Address entry)89 const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
90 for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
91 if (entry == kIntrinsicFunctions[i].entry) {
92 return &(kIntrinsicFunctions[i]);
93 }
94 }
95 return NULL;
96 }
97
98
FunctionForId(Runtime::FunctionId id)99 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
100 return &(kIntrinsicFunctions[static_cast<int>(id)]);
101 }
102
103
RuntimeFunctionTable(Isolate * isolate)104 const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) {
105 if (isolate->external_reference_redirector()) {
106 // When running with the simulator we need to provide a table which has
107 // redirected runtime entry addresses.
108 if (!isolate->runtime_state()->redirected_intrinsic_functions()) {
109 size_t function_count = arraysize(kIntrinsicFunctions);
110 Function* redirected_functions = new Function[function_count];
111 memcpy(redirected_functions, kIntrinsicFunctions,
112 sizeof(kIntrinsicFunctions));
113 for (size_t i = 0; i < function_count; i++) {
114 ExternalReference redirected_entry(static_cast<Runtime::FunctionId>(i),
115 isolate);
116 redirected_functions[i].entry = redirected_entry.address();
117 }
118 isolate->runtime_state()->set_redirected_intrinsic_functions(
119 redirected_functions);
120 }
121
122 return isolate->runtime_state()->redirected_intrinsic_functions();
123 } else {
124 return kIntrinsicFunctions;
125 }
126 }
127
128
operator <<(std::ostream & os,Runtime::FunctionId id)129 std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
130 return os << Runtime::FunctionForId(id)->name;
131 }
132
133
134 } // namespace internal
135 } // namespace v8
136