blob: 90f4e4ce3355ea698f778ac28eaf4ecd63d13363 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005#include "src/runtime/runtime.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006
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"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040012#include "src/runtime/runtime-utils.h"
13
14namespace v8 {
15namespace 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);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
22#undef F
Emily Bernierd0a1eb72015-03-24 16:35:39 -040023
24#define P(name, number_of_args, result_size) \
25 ObjectPair Runtime_##name(int args_length, Object** args_object, \
26 Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027FOR_EACH_INTRINSIC_RETURN_PAIR(P)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040028#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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039#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 } \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040044 ,
45
Emily Bernierd0a1eb72015-03-24 16:35:39 -040046static const Runtime::Function kIntrinsicFunctions[] = {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047 FOR_EACH_INTRINSIC(F)
48 FOR_EACH_INTRINSIC(I)
49};
Emily Bernierd0a1eb72015-03-24 16:35:39 -040050
Emily Bernierd0a1eb72015-03-24 16:35:39 -040051#undef I
52#undef F
53
54
55void 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),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 Handle<Smi>(Smi::FromInt(i), isolate), PropertyDetails::Empty());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040065 // The dictionary does not need to grow.
66 CHECK(new_dict.is_identical_to(dict));
67 }
68}
69
70
71const 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
83const 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
93const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
94 return &(kIntrinsicFunctions[static_cast<int>(id)]);
95}
96
97
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000098const 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400123std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
124 return os << Runtime::FunctionForId(id)->name;
125}
126
127} // namespace internal
128} // namespace v8