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