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