• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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